Harden OCI registry authentication - #1278
Conversation
Validate registry-provided bearer realms, restrict cross-origin credential forwarding, and add an explicit registry-to-auth-host compatibility option. Co-authored-by: Kaniska <kaniska244@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Hardens OCI registry Bearer-token authentication by validating registry-provided realm URLs, constraining cross-origin auth host usage, disabling token-request redirects, and ensuring service/scope are encoded to prevent SSRF and credential forwarding.
Changes:
- Add realm admission + credential-forwarding policy with built-in and user-configured registry→auth-host mappings.
- Disable redirects for token endpoint requests and rebuild anonymous fallback requests to avoid replaying credentials.
- Add focused tests for realm policy, redirect refusal, and query encoding; wire the new test into CI.
Show a summary per file
| File | Description |
|---|---|
| src/spec-configuration/httpOCIRegistry.ts | Implements realm validation, cross-origin auth-host policy, credential-forwarding rules, redirect suppression for token requests, and safe URL parameter encoding. |
| src/spec-utils/httpRequest.ts | Adds a no-redirect request helper and returns responseUrl to support validating challenges against the final registry response URL. |
| src/spec-node/devContainersSpecCLI.ts | Introduces the repeatable --allow-cross-origin-auth-host <registry>=<auth> global option and propagates configuration via env. |
| src/test/httpOCIRegistry.test.ts | Adds unit/integration-style tests for realm admission, credential forwarding, redirect refusal, and query encoding behavior. |
| .github/workflows/dev-containers.yml | Adds the new test to the CI matrix and excludes it from the “run all except above” batch to avoid duplicate execution. |
Review details
Tip
Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Suppressed comments (1)
src/spec-utils/httpRequest.ts:121
- requestResolveHeadersInternal treats any URL with hostname 'localhost' as plain HTTP, even when the URL scheme is https:. That silently downgrades https://localhost to an http request, which can break requests and can undermine scheme-based security decisions (including for token realms). Consider basing the transport strictly on the parsed protocol (and, if needed, handle localhost TLS separately).
const plainHTTP = parsed.protocol === 'http:' || parsed.hostname === 'localhost';
if (plainHTTP) {
output.write('Sending as plain HTTP request', LogLevel.Warning);
}
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Lite
|
Companion VS Code Dev Containers integration: microsoft/vscode-remote-containers#1235 |
Propagate cross-origin auth host mappings explicitly through command, resolver, and registry request parameters instead of serializing them through the process environment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Follow-up 7b8e496 removes the internal environment-variable bridge. The option now propagates explicitly as typed command/resolver/request state across OCI paths. It also sets yargs |
Treat an exact registry-to-auth-host mapping as authorization for the complete token exchange, including Docker identity and refresh tokens. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated trusted host-pair semantics in 87adb63: an exact HTTPS registry-to-auth-host mapping now authorizes both Basic and refresh/identity-token exchange. Added a real cross-authority Docker |
Use the literal HTTP authentication scheme instead of constructing it at runtime. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Review details
Suppressed comments (1)
src/spec-node/devContainersSpecCLI.ts:74
- This global escape hatch is not propagated by the
features testcommand. That handler drops the parsed value beforeFeaturesTestCommandInputreachesgenerateDockerParams, even though test scenarios launch dev containers and can resolve OCI Feature dependencies or inspect a custom base image. As a result, the option is accepted but has no effect for that OCI-consuming command. Thread it throughfeaturesCLI/test.tsandtestCommandImpl.tsintocreateDockerParams.
global: true,
- Files reviewed: 20/20 changed files
- Comments generated: 1
- Review effort level: Balanced
| return realmUrl.protocol === 'https:' | ||
| && isConfiguredCrossOriginAuthHost(registryUrl, realmUrl, crossOriginAuthHosts); |
Parse and validate token realms once before credential lookup and reuse that decision for the complete trusted authentication exchange. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Name the redirect-origin check after the requested registry credentials it protects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gate realm restrictions, registry credential origin checks, and token redirect refusal behind --oci-auth-hardening while preserving legacy behavior by default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated in 7c650d5: behavior-changing OCI authentication protections are now opt-in through |
Collect shadow diagnostics for blocked auth realms, registry redirects that prevent credential forwarding, and token redirects, and surface them in CLI results. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated in 3ba63a5: add shadow diagnostics for auth lookups that hardening would block, registry redirects that would prevent forwarding requested-registry credentials, and auth-server redirects. Diagnostics are logged and surfaced in CLI results. |
Document the opt-in OCI authentication hardening and compatibility diagnostics release. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Prepared version 0.89.0 and added the August 2026 changelog entry in 422a92e. |
Require a shared diagnostics collector, reuse test parameter helpers, and only report registry redirects that end in an authentication challenge and would change credential forwarding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Refined the registry redirect diagnostic in 987bbc7 so cross-origin content/blob redirects are ignored; it now reports only redirected 401/403 challenges that would change credential forwarding. |
Summary
Harden OCI Feature and Template authentication against registry-controlled Bearer realms that could trigger SSRF or forward registry credentials to an attacker-selected endpoint.
This builds on the work in #1276 while narrowing the change to the authentication boundary and adding a registry-scoped compatibility escape hatch for legitimate external token services.
Session Context
Key decisions from the development session:
--oci-auth-hardeningenables realm restrictions, the requested-registry credential-origin gate, and token redirect refusal.--allow-cross-origin-auth-host <registry-host>=<auth-host>is repeatable. A bare auth-host allowlist would let any workspace-selected registry invoke that host as a confused deputy.--oci-auth-hardening, token requests do not follow redirects. Normal registry requests retain existing redirect behavior, and the final response URL is used to validate the challenge origin.http://localhosttoken realms remain supported for local Feature development; remote HTTP realms remain rejected.Changes
--oci-auth-hardeningas the explicit opt-in for behavior-changing authentication protections.--allow-cross-origin-auth-host <registry-host>=<auth-host>mappings for enterprise registries.serviceandscopewithURL.searchParams.Validation
yarn type-checkyarn lintyarn packageFixes github/codespaces#24328.