feat: support allow-insecure HTTP dependencies#700
feat: support allow-insecure HTTP dependencies#700arika0093 wants to merge 10 commits intomicrosoft:mainfrom
Conversation
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR introduces an explicit opt-in flow for allowing HTTP (insecure) APM dependencies, including persisting that decision in apm.yml and preserving HTTP metadata during lockfile replays.
Changes:
- Add
--allow-insecureflag + globalallow-insecureconfig to gate installation ofhttp://dependencies. - Persist and replay HTTP dependency metadata (
is_insecure,allow_insecure) via manifest and lockfile. - Update docs and add unit tests covering HTTP parsing, lockfile round-trip, CLI behaviors, and cloning behavior.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_install_update.py | Adds lockfile replay/round-trip tests for insecure HTTP metadata. |
| tests/unit/test_install_command.py | Adds CLI tests for --allow-insecure and install-time security checks. |
| tests/unit/test_config_command.py | Adds config command + config function tests for allow-insecure. |
| tests/unit/test_canonicalization.py | Adds parsing/serialization tests for HTTP dependency handling. |
| tests/unit/test_auth_scoping.py | Ensures HTTP deps don’t fall back to SSH during clone attempts. |
| src/apm_cli/models/dependency/reference.py | Introduces is_insecure/allow_insecure, HTTP canonicalization, manifest serialization, and scheme-aware URLs. |
| src/apm_cli/drift.py | Preserves insecure scheme info during lockfile replay. |
| src/apm_cli/deps/lockfile.py | Persists is_insecure/allow_insecure in lockfile read/write and dependency refs. |
| src/apm_cli/deps/github_downloader.py | Adds HTTP-only clone path and URL building for insecure deps. |
| src/apm_cli/config.py | Adds get_allow_insecure / set_allow_insecure. |
| src/apm_cli/commands/install.py | Adds --allow-insecure, manifest writing behavior, and install-time HTTP enforcement. |
| src/apm_cli/commands/config.py | Generalizes config get/set to support allow-insecure. |
| src/apm_cli/commands/_helpers.py | Propagates HTTP/artifactory/local fields when computing install paths. |
| src/apm_cli/bundle/plugin_exporter.py | Propagates HTTP/artifactory/local fields for exported install paths. |
| packages/apm-guide/.apm/skills/apm-usage/commands.md | Documents --allow-insecure in the command reference table. |
| docs/src/content/docs/reference/cli-commands.md | Documents --allow-insecure and new config key. |
| docs/src/content/docs/guides/dependencies.md | Documents HTTP dependency manifest format + caution guidance. |
- add install/config handling for HTTP dependencies behind explicit opt-in - preserve apm.yml manifest consistency by using git: entries - update tests and documentation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Also honor global allow-insecure config when adding HTTP dependencies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
101a07a to
3a28c8c
Compare
sergio-sisternes-epam
left a comment
There was a problem hiding this comment.
Solid feature -- good security model with dual opt-in (dep-level + CLI/config), thorough test coverage (30+ tests), clean lockfile round-trip, and well-written docs. Nice work!
One blocking issue: to_apm_yml_entry() hardcodes allow_insecure = True, which could silently escalate security posture. See inline comment.
Also: this PR silently fixes a bug where artifactory_prefix was missing from DependencyReference construction in _helpers.py, plugin_exporter.py, and lockfile.py -- directly related to #614. Consider referencing that issue in the PR description.
| entry["ref"] = self.reference | ||
| if self.alias: | ||
| entry["alias"] = self.alias | ||
| entry["allow_insecure"] = True |
There was a problem hiding this comment.
Blocking: This hardcodes allow_insecure = True for all HTTP deps, ignoring self.allow_insecure. If this method is reused in a code path that hasn't applied the opt-in check, it silently grants insecure access.
| entry["allow_insecure"] = True | |
| entry["allow_insecure"] = self.allow_insecure |
| ado_project=ado_project, | ||
| ado_repo=ado_repo, | ||
| artifactory_prefix=artifactory_prefix, | ||
| is_insecure=dependency_str.startswith("http://"), |
There was a problem hiding this comment.
Suggestion: startswith("http://") is case-sensitive, but URL schemes are case-insensitive per RFC 3986. HTTP://host/repo would bypass insecure detection.
| is_insecure=dependency_str.startswith("http://"), | |
| is_insecure=urllib.parse.urlparse(dependency_str).scheme.lower() == "http", |
| return build_ssh_url(host, repo_ref) | ||
| elif is_github and github_token: | ||
| # Only send GitHub tokens to GitHub hosts | ||
| # # Only send GitHub tokens to GitHub hosts |
There was a problem hiding this comment.
Nit: Double # — typo from the refactor commit.
| # # Only send GitHub tokens to GitHub hosts | |
| # Only send GitHub tokens to GitHub hosts |
| sub_path = entry.get("path") | ||
| ref_override = entry.get("ref") | ||
| alias_override = entry.get("alias") | ||
| allow_insecure = bool(entry.get("allow_insecure", False)) |
There was a problem hiding this comment.
Suggestion: bool(entry.get("allow_insecure", False)) treats any non-empty string (e.g., "false") as True. Since this is a security-relevant field, consider validating the type explicitly:
| allow_insecure = bool(entry.get("allow_insecure", False)) | |
| allow_insecure = entry.get("allow_insecure", False) | |
| if not isinstance(allow_insecure, bool): | |
| raise ValueError("'allow_insecure' field must be a boolean") |
…ing for allow-insecure config
|
@sergio-sisternes-epam On #614: this PR now explicitly passes |
Description
This PR adds explicit support for HTTP (insecure) APM dependencies behind an opt-in flow, and makes lockfile replays preserve that HTTP source information.
When adding a package, you can explicitly allow HTTP dependencies by providing the
--allow-insecureflag.When restoring packages, you also need to provide the
--allow-insecureflag unless the global config is enabled. If there are HTTP URLs in the dependency chain, it will error without--allow-insecureorapm config set allow-insecure true.The
apm.ymlfile will record it in the following format:HTTP dependencies require two explicit signals:
allow_insecure: trueon the dependency entry inapm.ymlapm install --allow-insecureorapm config set allow-insecure trueThe global configuration only removes the need to pass
--allow-insecureon the CLI. It does not remove theallow_insecure: truerequirement inapm.yml.Fixes #636
TODO
--allow-insecureflag when adding dependencies--allow-insecureflag when installing dependenciesallow_insecure: truefield inapm.ymland lockfileallow-insecureglobal configType of change
Testing