feat(compile): add internal supply-chain feed/registry mirror#1080
Conversation
Add an optional supply-chain: front-matter section that reroutes the four GitHub/GHCR fetches (ado-aw compiler, AWF binary, ado-script bundle, AWF/MCPG images) to an internal Azure DevOps Artifacts feed and/or container registry. Default path is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Good design and solid validation, but one likely runtime bug in the AWF image tagging strategy that the compile-time tests won't catch. Findings🐛 Bugs / Logic Issues
🔒 Security Concerns
|
Address Rust PR review feedback on the supply-chain mirror:
- Bug: prepull_images_step tagged the AWF squid/agent :latest aliases onto the
internal registry, but run_agent_step invokes AWF with --skip-pull and no
image-name flags, so AWF resolves its built-in ghcr.io/.../{squid,agent}:latest
names — absent from the local cache. Now the :latest aliases always use the
GHCR names AWF expects, tagged from the internally pulled image.
- Hoist a single NuGetAuthenticate@1 per job (feed_auth_step) instead of one per
artifact, reducing redundant idempotent auth steps.
- Add a SAFETY note to extract_package_payload_bash documenting that callers
must pass only trusted compile-time-constant strings.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Thanks for the review — all three points addressed in c33f671: 🐛 Bug — AWF So the firewall containers are present in the local Docker cache at runtime. Added regression assertions ( 🔒
Validation: |
🔍 Rust PR ReviewSummary: Looks good overall — well-structured feature with solid security hygiene, but one logic inconsistency in the agent job's auth step count that contradicts the PR's own stated design. Findings🐛 Bugs / Logic Issues
The PR description says "Hoist one
This doesn't cause a runtime failure (NuGetAuthenticate@1 is idempotent), but it's a concrete gap between the design claim and the generated output. The test assertion The fix: since
|
|
@copilot we need to consider that the configured internal feed may have a different "prefix" than GitHub. It is unlikely teams will be able to publish to the GitHub acr host. We should allow users to provide the full registry base path. Our contract is the artifact names must remain the same under that path. |
Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
Done in the latest commit. Changes:
|
|
/rust-review |
|
✅ Rust PR Reviewer completed successfully! |
🔍 Rust PR ReviewSummary: Looks good overall — well-structured, secure design with typed newtypes and validated inputs. Two issues worth fixing before merge. Findings🐛 Bugs / Logic Issues
assert!(
compiled.contains(
"docker tag myacr.azurecr.io/oss-mirror/squid:0.27.3 ghcr.io/..."
),This is a binary-only crate, so // Instead of an exact version match, check both halves independently:
assert!(
compiled.contains("docker tag myacr.azurecr.io/oss-mirror/squid:")
&& compiled.contains(" ghcr.io/github/gh-aw-firewall/squid:latest"),
"AWF squid image must be re-tagged to the GHCR :latest name AWF expects"
);🔒 Security Concerns
The validator uses a deny-list (no quotes/control chars) but doesn't filter supply-chain:
registry:
name: myacr.azurecr.io
service-connection: "$(my.shared.conn)"produces
|
…ic image-tag test
Address Rust PR review feedback:
- Tests: replace hardcoded AWF_VERSION (0.27.3) in the :latest re-tag
assertions with version-agnostic split contains() checks, so an AWF_VERSION
bump can't cause spurious failures in this binary-only crate.
- Security: is_valid_service_connection now rejects ADO expression / pipeline-
command sequences ($( , ${{ , $[ , ##vso[ , ##[) so a connection value cannot
be expanded as a pipeline variable at queue time, matching the codebase's
reject_pipeline_injection convention.
- Docs: note the Azure Private Link caveat for acr_registry_name / registry.name
(use the canonical *.azurecr.io login server) in the function comment and
docs/supply-chain.md.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Thanks — addressed in ec36cf8: 🐛 Hardcoded 🔒
Validation: |
🔍 Rust PR ReviewSummary: Looks good — well-structured feature with no blocking issues. A few minor concerns worth addressing. Findings
|
…ion job Addresses review feedback plus two latent bugs found while re-evaluating against main (which now has the supply-chain mirror feature, #1080): - Conclusion job now reuses ado_script::install_and_download_steps_typed, which (a) respects the supply-chain feed mirror and (b) unzips to /tmp/ado-aw-scripts/ (the hand-rolled copy double-nested to /tmp/ado-aw-scripts/ado-script/ado-script/, so conclusion.js was never at the referenced path). - release.yml now auto-globs ado-script/*.js instead of a manual file list, so every built bundle ships. conclusion.js was missing from the manual list and would never have reached a release. - New bundle-coverage vitest guards that every src/<name>/ bundle dir is wired into the npm build chain (the safety net for auto-globbing). - buildTitle truncates to ADO's 255-char System.Title limit. - Ported the WIQL trust-boundary comment to wit.ts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Adds an optional
supply-chain:front-matter section that lets a compiled agentic pipeline pull its artifacts from an internal Azure DevOps Artifacts feed and/or internal container registry instead of GitHub Releases / GHCR — for supply-chain-hardened environments where the build agent pool cannot reach GitHub/GHCR. When the section is omitted, the generated pipeline is byte-for-byte unchanged.The four rerouted fetch points:
ado-awcompilergithub.com/githubnext/ado-awreleasesgithub.com/github/gh-aw-firewallreleasesado-script.zipbundlegithub.com/githubnext/ado-awreleasesghcr.io/github/...Configuration
Design highlights
NuGetAuthenticate@1+DownloadPackage@1+ unzip/relocate, preserving the existingsha256sum -c checksums.txtverification. Same-org feeds authenticate via$(System.AccessToken)(no service connection needed).az acr login(AzureCLI@2) + registry rewrite in both the pre-pull step and the MCPGdocker run, via a sharedimage_refhelper so the two call sites can't drift.registry.nameaccepts a full registry host or base path (e.g.myacr.azurecr.io/oss-mirror,contoso.azurecr.io/team/oss/mirror) — since teams generally cannot publish under GHCR'sgithub/...namespace, the original prefix is not preserved; only the artifact name (squid,agent,gh-aw-mcpg) is placed directly under the configured base path at the same tag.az acr loginderives the ACR name from the host portion. The local:latestaliases are still tagged to the GHCR names AWF resolves with--skip-pull.$(System.AccessToken); the registry requires a service connection (ACR has no$(System.AccessToken)path) — compilation fails otherwise.feed/registryeach accept their ownservice-connection, with a top-level fallback, so the two targets can use different connections.FeedRef,RegistryRef, andServiceConnectionnewtypes (src/secure.rs/src/validate.rs); theRegistryRefvalidator allows multi-segment base paths while rejecting..,//, leading/trailing/, ports, and shell metacharacters.SupplyChainConfigusesdeny_unknown_fieldsand validated newtypes per the repo's parse-don't-validate convention.build_pipeline_context.Finding (documented, no code change)
The AWF firewall wraps only the copilot agent command (
awf … -- '<engine_run>'); the mirror fetches run as ordinary ADO steps outside the sandbox. They therefore need no--allow-domainsallowlist entry, and strippinggithub.comwould be wrong. Documented inAGENTS.md(Security Considerations → Network Isolation) anddocs/supply-chain.md.Test plan
cargo build✓cargo clippy --all-targets --all-features— clean ✓cargo test— 2043 unit tests + all integration suites, 0 failures ✓tests/compiler_tests.rs(full reroute, absent-section default, feed-only/SAT, registry-without-connection error, top-level fallback); the full-reroute test uses a registry base path (myacr.azurecr.io/oss-mirror) and guards that the GHCRgithub/...prefix is not carried under itSupplyChainConfigdeserialization/resolution/validation (including registry base-path acceptance) and theFeedRef/RegistryRef/ServiceConnectionvalidatorscargo test --test bash_lint_tests(shellcheck) ✓ —tests/fixtures/supply-chain-agent.mdexercises the new bash bodiesnpm run build✓ — all internal links valid; newreference/supply-chainpage added to the sidebarDocs
docs/supply-chain.mdandsite/src/content/docs/reference/supply-chain.mdx(including the registry base-path contract)docs/front-matter.mdgrammar and theAGENTS.mddoc index