Skip to content

use the registry host for the scoped buildx config dir - #1083

Open
breken-ai wants to merge 1 commit into
docker:masterfrom
breken-ai:fix-scope-registry-scheme
Open

breken-ai wants to merge 1 commit into
docker:masterfrom
breken-ai:fix-scope-registry-scheme

Conversation

@breken-ai

Copy link
Copy Markdown

When scope is set, scopeToConfigDir joins the registry onto the Buildx config dir exactly as it was given. If the registry is a URL, the path becomes config/https:/<host>/<scope>. Buildx's parseConfigKey (util/dockerutil/dockerconfig/configprovider.go) reads the first path element as the host. It gets https: as the host and never uses these credentials.

This always happens for a scoped ECR login. loginECR runs docker login against the proxyEndpoint from GetAuthorizationToken, and that value is a URL (https://012345678910.dkr.ecr.eu-west-3.amazonaws.com). So this setup

- uses: docker/login-action@v4
  with:
    registry: 012345678910.dkr.ecr.eu-west-3.amazonaws.com
    username: ${{ vars.AWS_ACCESS_KEY_ID }}
    password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    scope: myapp@push

writes the credentials to ~/.docker/buildx/config/https:/012345678910.dkr.ecr.eu-west-3.amazonaws.com/myapp@push. Buildx never reads that directory, so the push is not authenticated. Logout in the post step targets a different directory: it computes the path from the registry input, which has no scheme. The same thing happens with any registry written as a URL, such as registry: https://ghcr.io.

Fix: remove the URL scheme and any trailing slashes before building the path. Then login, logout and Buildx all use config/<host>/<scope>. The existing checks for paths that escape the Buildx config dir still run on the result.

Tests

  • scopeToConfigDir uses the registry host for %s (context.test.ts): covers https://ghcr.io, https://ghcr.io/, http://localhost:5000, an ECR proxy endpoint and https://docker.io.
  • loginECR writes scoped credentials to the config dir of the registry host (docker.test.ts): mocks getRegistriesData with a URL proxy endpoint, checks that DOCKER_CONFIG for docker login is config/<host>/myapp@push, and checks that it matches the configDir that getAuthList saves for logout.
  • On master, 6 of these fail. For example: Received: ".../buildx/config/https:/012345678910.dkr.ecr.eu-west-3.amazonaws.com/myapp@push". With the fix, all 86 pass.
  • yarn lint and tsc --noEmit pass. dist/ is rebuilt with yarn build, and only index.cjs and its sourcemap change.

AI disclosure: I found and fixed this with help from an AI assistant (Claude). I checked the change and the tests myself.

🤖 Generated with Claude Code

scopeToConfigDir joined the registry as given onto the Buildx config
dir. For a registry given as a URL this produced
config/https:/<host>/<scope>, and Buildx parses the first path element
as the registry host, so it never finds these credentials.

ECR always hits this: loginECR logs in to the proxy endpoint returned by
GetAuthorizationToken, which is a URL (https://<id>.dkr.ecr.<region>.amazonaws.com),
so a scoped ECR login wrote its credentials to a directory Buildx does
not read, and logout looked in a different directory than login wrote to.

Drop the URL scheme and trailing slashes before building the path.

Assisted-By: Claude
Signed-off-by: breken-ai <312387581+breken-ai@users.noreply.github.com>
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.

1 participant