Skip to content

gcrhelper: add automatic GCR/Artifact Registry auth on GCE#1124

Open
jossy wants to merge 9 commits intocloudfoundry:developfrom
jossy:develop
Open

gcrhelper: add automatic GCR/Artifact Registry auth on GCE#1124
jossy wants to merge 9 commits intocloudfoundry:developfrom
jossy:develop

Conversation

@jossy
Copy link
Copy Markdown

@jossy jossy commented Apr 10, 2026

Checklist

  • CLA signed (individual or corporate) with the Cloud Foundry Foundation
  • Run ./scripts/test-in-docker.bash: all tests pass

Summary

Diego cells running on Google Cloud (GCE) have a VM service account that can be granted access to GCR / Artifact Registry via IAM. Despite this, cf push --docker-image gcr.io/... currently requires the operator or developer to explicitly pass --docker-username / --docker-password and store those credentials with the app. This creates unnecessary credential management overhead and makes credential rotation difficult.

ECR already has equivalent automatic auth via ecrhelper. This PR mirrors that pattern for GCR and Artifact Registry.

We have deployed these changes successfully in one of our own GCE-hosted CF environments and confirmed end-to-end that cf push --docker-image eu.gcr.io/... works without credentials.

Dependency: cloudfoundry/rep#82 must be merged with this PR, as it contains the conversion_helpers.go change for the runtime path.

Changes

New package: gcrhelper

Mirrors the structure of ecrhelper. Provides a GCRHelper interface with two methods:

  • IsGCRRepo(url): regex match against *.gcr.io and *.pkg.dev (Artifact Registry's domain)
  • GetGCRCredentials(): calls the GCE instance metadata server (http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token) to get a short-lived OAuth2 token, returned as the password alongside the fixed username oauth2accesstoken

On first metadata server failure (non-GCE environment or unreachable network), notOnGCE is set on the helper and subsequent calls return empty credentials immediately without a network attempt. The token is fetched on every call rather than cached, since the GCE metadata server always returns a token with the correct remaining TTL and handles refresh transparently.

The Metadata-Flavor: Google request header is set as required by the metadata server.

rep/conversion_helpers.go

In convertCredentials(), before the existing ECR check: if no credentials are stored for a docker image (username == "" && password == ""), check whether the image is on GCR/Artifact Registry and, if so, call GetGCRCredentials(). Falls back to the existing path (empty credentials → unauthenticated pull) if gcrhelper returns nothing.

dockerapplifecycle/builder/builder_runner.go and main.go

Same guard added to getCredentials() in the staging path. GCRHelper field added to the Builder struct; wired in main.go with NewGCRHelper().

BOSH package specs

gcrhelper/*.go added as a gosub dependency to all six affected packages: rep, auctioneer, bbs, cfdot, rep_windows, docker_app_lifecycle.

Operator notes

  • On GCE, the staging container (dockerapplifecycle builder) runs inside a Garden container and cannot reach 169.254.169.254 without a staging ASG. Operators on GCE will need to add {"protocol":"tcp","destination":"169.254.169.254/32","ports":"80"} as a staging security group rule. The runtime path (rep) runs on the host VM via BPM and is unaffected.
  • No IAM configuration is included in this PR; granting the cell service account roles/artifactregistry.reader on the relevant repository is an operator responsibility.
  • The existing CF documentation at https://docs.cloudfoundry.org/devguide/deploy-apps/push-docker.html#gcr only describes the JSON key file approach. If this PR is accepted, we are happy to follow up with a documentation PR adding a new section for GCE VM service account auth, modelled on the equivalent ECR section.

Backward Compatibility

Breaking Change? No

The new code only runs when no credentials are stored for the image (username == "" && password == ""). All existing deployments that pass credentials are completely unaffected. On non-GCE environments, the metadata server call fails within 1 second, notOnGCE is set, and all subsequent calls return empty credentials immediately, identical behaviour to the current code path.

Scenario Behaviour
GCE, no stored credentials Automatic auth via VM service account. Zero config required.
GCE, credentials stored Existing credentials used as-is. No change.
Non-GCE Metadata call fails in ≤1s, falls back to empty credentials. No regression.
Non-GCR image New code not reached.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

1 participant