feat(oci): support OCI auth hardening from reference v0.89.0 - #24
Merged
Merged
Conversation
ResolveBuildAuth resolves credentials through the docker config and, when that file is missing, through the platform credential helper. The tests passed no DOCKER_CONFIG, so on a developer machine they resolved the real ghcr.io/docker.io credentials, asserted against whatever the host was logged into, and printed that credential in the failure message. Point them at a DOCKER_CONFIG holding credentials for an unrelated registry: present, so the platform-helper fallback stays out, and irrelevant to every registry under test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bump the pinned reference CLI to v0.89.0 and implement the observable surface it added (PR devcontainers/cli#1278): - `--oci-auth-hardening` and `--allow-cross-origin-auth-host` as global flags, with the same validation the oracle applies: the allow list requires hardening, and each entry is a '<registry-host>=<auth-host>' pair of bare authorities. - `ociAuthDiagnostics` in the `up`, `build` and `read-configuration` output, reporting what hardening would change. - Bearer realms pinned to the registry authority or a trusted auth host (including the built-in Docker Hub and GitLab mappings), and token endpoints refused a redirect, when hardening is on. - `scheme` on the feature ref in `read-configuration` output, and the generated feature Dockerfiles defaulting the base-image ARG to `scratch` rather than `placeholder`. The policy is built once per invocation and carried on the command context, so every OCI client of a command shares its settings and feeds the same diagnostics. `exec` parses its own flags and therefore applies the validation itself; `features test` re-invokes this binary and forwards the flags to the `up` it spawns. The hardening is enforced in a transport above oras-go, which already refuses to forward credentials to a cross-origin challenge. That makes hardening-off stricter here than upstream; the divergence is documented and the diagnostics still report what hardening would change. TestOracleFlagCoverage only inspected per-command options, so the two new global flags went unnoticed; it now checks the oracle's global options as well, and TestFlagInventoryParity pins them to the root command. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CodeQL reported "Workflow does not contain permissions" for every job of go-cli.yml except lint-and-test: without a `permissions` block the token inherits the repository default, which may include write scopes the jobs never need. Declare `contents: read` once at the workflow level. Every job only checks out the repo and reads the API (setup-task's repo-token), and artifact upload/download uses the Actions runtime token, so read is sufficient; a future job that needs more widens it for itself. TestWorkflowsDeclarePermissions pins the rule for all workflows (top-level or per-job), and TestGoCLIWorkflowIsReadOnlyByDefault pins this grant, so a job added later cannot silently inherit write access. Both fail without the block: the first names all seven unprotected jobs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps the pinned reference CLI from v0.88.0 to v0.89.0 and implements the observable surface that release added (devcontainers/cli#1278).
What changed
New global flags
--oci-auth-hardeningand--allow-cross-origin-auth-host, with the oracle's validation: the allow list requires hardening, and each entry is a<registry-host>=<auth-host>pair of bare authorities. Error messages and exit codes match the reference verbatim.New output field
ociAuthDiagnosticsonup,buildandread-configuration, reporting the three compatibility flags so the hardening's impact can be measured before enabling it.Hardening behavior: bearer realms pinned to the registry authority or a trusted auth host (including the built-in Docker Hub and GitLab mappings), and token endpoints refused a redirect.
Two smaller v0.89.0 changes:
schemeon the feature ref inread-configurationoutput, and the generated feature Dockerfiles defaulting the base-image ARG toscratchinstead ofplaceholder.The policy is built once per invocation and carried on the command context, so every OCI client of a command shares its settings and feeds the same diagnostics.
execparses its own flags (DisableFlagParsing) and therefore applies the validation itself;features testre-invokes this binary and forwards the flags to theupit spawns.Divergence
The hardening is enforced in a transport above
oras-go, which already refuses to forward credentials to a cross-origin challenge (GHSA-vh4v-2xq2-g5cg). Hardening off is therefore already stricter here than upstream. Recorded indocs/DIVERGENCES.md; the diagnostics still report what hardening would change, so the flag remains a faithful compatibility probe.Test-gap fix
TestOracleFlagCoverageonly inspected per-command options, which is why the two new global flags slipped through. It now checks the oracle's global options too, andTestFlagInventoryParitypins them to the root command.TestResolveBuildAuthFromOCIEnvAndGitHubTokenread the developer's real~/.docker/config.jsonand asserted against whatever the host was logged into (printing that credential on failure). Fixed in its own commit.Validation
task lint,task build,task referencetask test:racetask spec:compliancetask parity:contracttask parity:semantictask parity:networktask parity:publish,task test:integrationtask vulntask test:e2etask parity:runtimeFive new parity cases cover the flags end to end; new unit tests cover the parser, the realm policy, each diagnostic, the hardening refusals, an end-to-end fetch through the real client against a fake registry, and the CLI-level flag validation, output field, context plumbing and flag forwarding.
Two environment notes from the local run, neither related to this change: the runtime lane still reports 13 inconclusive compose cases where both CLIs fail identically (the local daemon's runc cannot start a container joining another container's network namespace), and the e2e plus a few runtime cases need
BUILDX_BUILDER=defaulton a host whose default buildx builder uses thedocker-containerdriver.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.