Skip to content

Add delegated registry authentication to Gantry#465

Merged
vpatelsj merged 4 commits into
mainfrom
gantry/delegated-registry-auth
Jul 14, 2026
Merged

Add delegated registry authentication to Gantry#465
vpatelsj merged 4 commits into
mainfrom
gantry/delegated-registry-auth

Conversation

@vpatelsj

Copy link
Copy Markdown
Contributor

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-Authenticate challenge 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

  • Add challenge discovery for configured HTTPS registries:
    • 200 identifies an anonymous registry.
    • 401 relays validated Basic or Bearer challenges.
  • Support both Basic credentials and scoped Bearer tokens.
  • Forward authorization through peer fetches, background pulls, and please_pull.
  • Update the coordination protocol to /gantry/coord/1.1.0.
  • Keep credentials request-scoped and in memory only.
  • Prevent rejected delegated authorization from falling back to the puller node’s identity.
  • Retain credentials_path as an explicit legacy shared-identity mode.
  • Add validation for malformed, unsupported, oversized, and insecure authorization flows.
  • Update deployment manifests, operator documentation, and detailed design documentation.

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:

  • Private ACR with anonymous access and admin credentials disabled.
  • Requester node performed zero ACR origin pulls.
  • Designated Gantry peers fetched the manifest and layers.
  • Warm pulls reused peer content without additional origin requests.
  • Separate HTTPS Basic registry successfully delegated authorization across nodes.
  • Unauthenticated Basic pull was rejected before any origin work.
  • Gantry had no shared registry credential Secret or configured credential path.

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_pull credential 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and please_pull.
  • Adds upstream registry challenge discovery/caching and relays validated Basic/Bearer WWW-Authenticate challenges back to containerd; propagates challenges on auth failures.
  • Updates the coordination protocol and protobuf schema to /gantry/coord/1.1.0 to carry delegated authorization in PleasePullRequest.

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.

Comment thread internal/gantry/origin/origin.go Outdated
@vpatelsj vpatelsj marked this pull request as ready for review July 14, 2026 14:10
@vpatelsj vpatelsj requested a review from a team July 14, 2026 14:10
@vpatelsj vpatelsj added this pull request to the merge queue Jul 14, 2026
Merged via the queue into main with commit e78fb4c Jul 14, 2026
26 checks passed
@vpatelsj vpatelsj deleted the gantry/delegated-registry-auth branch July 14, 2026 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants