Add delegated registry authentication to Gantry#465
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds delegated, request-scoped registry authentication to Gantry so that private-registry pulls can reuse the requesting workload’s existing kubelet/CRI credentials (via containerd challenge/authorizer flow) without distributing shared credentials across all Gantry nodes.
Changes:
- Introduces a request-scoped authorization carrier (
internal/gantry/registryauth) and threads it through mirror requests, peer transfers, coldstart prefetch, andplease_pull. - Adds upstream registry challenge discovery/caching and relays validated Basic/Bearer
WWW-Authenticatechallenges back to containerd; propagates challenges on auth failures. - Updates the coordination protocol and protobuf schema to
/gantry/coord/1.1.0to carry delegated authorization inPleasePullRequest.
Reviewed changes
Copilot reviewed 27 out of 28 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| internal/gantry/transfer/client.go | Forwards delegated Authorization header on peer fetch requests. |
| internal/gantry/transfer/client_test.go | Adds coverage ensuring peer fetches forward delegated authorization. |
| internal/gantry/registryauth/registryauth.go | New package to normalize/store/detach delegated registry authorization in context. |
| internal/gantry/registryauth/registryauth_test.go | Unit tests for authorization normalization and detaching behavior. |
| internal/gantry/proto/coord/v1/generate.go | Adds go:generate entrypoint for regenerating coord protobuf bindings. |
| internal/gantry/proto/coord/v1/coord.proto | Bumps protocol docs to 1.1.0 and adds authorization field to PleasePullRequest. |
| internal/gantry/proto/coord/v1/coord.pb.go | Regenerated protobuf output reflecting schema/version updates and modern timestamp type. |
| internal/gantry/origin/origin.go | Implements challenge discovery/caching and enforces request-scoped delegated auth semantics for origin pulls. |
| internal/gantry/origin/origin_test.go | Adds extensive tests covering anonymous/basic/bearer challenges, delegation, and non-poisoning behavior. |
| internal/gantry/mirror/mirror.go | Captures inbound auth, returns challenges to containerd, detaches auth into background prefetch, and propagates challenges on 401s. |
| internal/gantry/mirror/mirror_test.go | Adds tests for inbound auth capture, malformed auth handling, and negative-cache behavior under delegation. |
| internal/gantry/mirror/mirror_prefetch_test.go | Ensures prefetch detaching retains delegated authorization. |
| internal/gantry/mirror/mirror_auth_test.go | Adds handshake tests verifying containerd’s Basic/Bearer auth flow against relayed challenges. |
| internal/gantry/ifaces/ifaces.go | Extends interfaces/contracts to carry challenge info and require forwarding delegated auth in peer dialer. |
| internal/gantry/coord/coord.go | Bumps protocol ID to 1.1.0 and forwards delegated authorization through please_pull. |
| internal/gantry/coord/coord_test.go | Tests that please_pull forwards delegated authorization end-to-end. |
| internal/gantry/config/config.go | Updates config documentation and safety messages to match new auth model. |
| internal/gantry/coldstart/prefetch_test.go | Tests that prefetch calls propagate delegated authorization into PleasePull. |
| internal/gantry/coldstart/coldstart.go | Adjusts trusted-failure-class logic when a request carries delegated authorization. |
| internal/gantry/coldstart/coldstart_test.go | Adds tests for bypassing credential-specific cooldowns when delegated auth is present. |
| go.mod | Drops direct dependency on github.com/golang/protobuf (now using google.golang.org/protobuf types). |
| designs/gantry-detailed-design.md | Updates design documentation to describe delegated auth model and protocol changes. |
| deploy/gantry/README.md | Documents delegated auth behavior and clarifies legacy shared-identity mode. |
| deploy/gantry/hosts.toml.template | Removes loopback skip_verify guidance and documents why verified TLS matters for Bearer realms. |
| deploy/gantry/daemonset.yaml | Clarifies Secret mount as optional legacy shared-identity mode. |
| deploy/gantry/configmap.yaml | Documents delegated challenge negotiation and legacy credentials_path behavior. |
| cmd/gantry/origin_pull_test.go | Adds tests ensuring background pulls retain delegated auth and do not poison shared negative cache. |
| cmd/gantry/main.go | Threads detached authorization into background origin pulls and adjusts negative-cache recording/trust logic. |
Files not reviewed (1)
- internal/gantry/proto/coord/v1/coord.pb.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jwilder
approved these changes
Jul 14, 2026
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.
Updated todo list
Summary
Enable Gantry to pull from private registries using the requesting workload’s existing registry authorization, without distributing shared credentials to every Gantry node.
When a registry requires authentication, requester Gantry relays the upstream
WWW-Authenticatechallenge to containerd. Containerd uses the credential supplied by kubelet or CRI to complete the Basic or Bearer flow, then retries Gantry with the resulting request-scoped authorization. Gantry forwards that authorization to whichever peer is selected to pull the content from the origin.Changes
200identifies an anonymous registry.401relays validated Basic or Bearer challenges.please_pull./gantry/coord/1.1.0.credentials_pathas an explicit legacy shared-identity mode.Validation
Validated unit and integration coverage for anonymous, Basic, and Bearer registries, challenge caching, peer forwarding, asynchronous pulls, and cross-node coordination.
Also validated on a 10-node AKS cluster:
Security Notes
Bearer token acquisition remains with containerd; Gantry receives only the resulting scoped token. Delegated credentials are never persisted or cached and are discarded after the request.
The
please_pullcredential travels over encrypted libp2p. Peer HTTP transfer currently uses plaintext h2c, so forwarding authorization requires a trusted cluster network or an additional encryption layer such as a service mesh.