Skip to content

Fix image pull auth for non-Docker Hub registries#458

Merged
jchangx merged 3 commits intodocker:mainfrom
jchangx:fix/dhi-registry-auth
Mar 30, 2026
Merged

Fix image pull auth for non-Docker Hub registries#458
jchangx merged 3 commits intodocker:mainfrom
jchangx:fix/dhi-registry-auth

Conversation

@jchangx
Copy link
Copy Markdown
Contributor

@jchangx jchangx commented Mar 26, 2026

Summary

  • The gateway only passed RegistryAuth for docker.io/ prefixed images, causing 401 Unauthorized errors when pulling from other registries (e.g. dhi.io for Docker Hardened Images of MCP servers) even when valid credentials existed in the Docker credential store
  • For non-docker.io registries, use Docker CLI's own command.RetrieveAuthTokenFromImage to resolve credentials from the credential store — the same auth path that docker pull uses natively
  • This correctly handles all credential types (username/password, IdentityToken), base64url encoding, and hostname normalization
  • Docker Hub continues to use the existing Desktop /registry/token path
  • No Docker Desktop dependency for the new path — works with any credential helper (osxkeychain, secretservice, etc.)

Test plan

  • docker mcp catalog pull docker/mcp-catalog-dhi then docker mcp gateway run — dhi.io images should pull without 401 errors
  • Verify docker.io image pulls still work as before
  • Verify registries with no stored credentials gracefully fall back to anonymous pull

🤖 Generated with Claude Code

@jchangx jchangx requested a review from a team as a code owner March 26, 2026 01:39
@jchangx jchangx requested a review from bobbyhouse March 26, 2026 01:40
Docker Desktop mirrors Hub credentials to dhi.io on login (pinata
b497446ff36), but the gateway only passed registry auth for docker.io
images. This caused 401 errors when pulling dhi.io images even though
valid credentials existed in the credential store.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jchangx jchangx marked this pull request as draft March 26, 2026 01:44
The gateway only passed registry auth for docker.io images, causing 401
errors when pulling from other registries (e.g. dhi.io) even when valid
credentials existed in the Docker credential store.

For non-docker.io registries, resolve credentials from the standard
Docker CLI credential store (ConfigFile().GetAuthConfig), which works
with any credential helper (osxkeychain, secretservice, etc.) and does
not require Docker Desktop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jchangx jchangx force-pushed the fix/dhi-registry-auth branch from ab9e1d5 to 47b54b9 Compare March 26, 2026 01:49
@jchangx jchangx changed the title Fix image pull auth for dhi.io registry Fix image pull auth for non-Docker Hub registries Mar 26, 2026
@jchangx jchangx requested a review from saucow March 26, 2026 01:51
@jchangx jchangx marked this pull request as ready for review March 26, 2026 01:51
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47b54b9f81

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Replace hand-rolled credential encoding with command.RetrieveAuthTokenFromImage
which correctly handles IdentityToken auth, base64url encoding, and hostname
normalization — the same auth path docker pull uses natively.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jchangx jchangx force-pushed the fix/dhi-registry-auth branch from 51048ed to 2fddfaf Compare March 26, 2026 01:56
@bobbyhouse
Copy link
Copy Markdown
Contributor

bobbyhouse commented Mar 26, 2026

question: I get an error in docker desktop when trying to go into a dhi server. I guess that has more to do with the way the catalog is built/docker desktop expects and less to do with authentication?

Screenshot 2026-03-26 at 12 24 06 PM

@bobbyhouse
Copy link
Copy Markdown
Contributor

bobbyhouse commented Mar 26, 2026

question: this experience have something to do with these changes? Seems odd because it appear to work fine for dhi, but I get some kind of auth related issue for the docker mcp catalog?

➜  mcp-gateway git:(main) docker mcp gateway run --profile profile
- Reading profile configuration...
  - Loading 2 catalog(s) for dynamic tools
    - Processing catalog 'docker/mcp-catalog-dhi:latest' with 11 servers
    - Processing catalog 'roberthouse224/our-catalog:latest' with 7 servers
  - Total servers loaded from all catalogs: 18
- Configuration read in 79.807625ms
- Using images:
  - dhi.io/context7-mcp:latest
  - mcp/playwright@sha256:082a1c37208cdcb216aee6943f8d8bbe23f1c59d827b2101e1f06e6f778cc105
  - warning: pulling docker image mcp/playwright@sha256:082a1c37208cdcb216aee6943f8d8bbe23f1c59d827b2101e1f06e6f778cc105: Error response from daemon: authentication required - incorrect username or password> Images pulled in 524.564083ms
- Those servers are enabled: playwright, context7-mcp
- Listing MCP tools...
  - Running dhi.io/context7-mcp:latest with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=context7-mcp -l docker-mcp-transport=stdio -e MCP_TRANSPORT]
  - Running mcp/playwright with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=playwright -l docker-mcp-transport=stdio]
  > Can't start playwright: failed to connect: calling "initialize": EOF
^C  > Can't start context7-mcp: failed to connect: context canceled
> 0 tools listed in 27.118061666s
- Adding internal tools (dynamic-tools feature enabled)
  > mcp-find: tool for finding MCP servers in the catalog
  > mcp-add: tool for adding MCP servers to the registry
  > mcp-remove: tool for removing MCP servers from the registry
  > code-mode: write code that calls other MCPs directly
  > mcp-exec: execute tools that exist in the current session
  > mcp-config-set: tool for setting configuration values for MCP servers
  > mcp-create-profile: tool for creating or updating profiles with current gateway state
  > mcp-activate-profile: tool for activating saved profiles
  > mcp-discover: prompt for learning about dynamic server management
docker Desktop is not running: Docker Desktop is not running
➜  mcp-gateway git:(main) docker login
Authenticating with existing credentials... [Username: roberthouse224]

i Info → To login with a different account, run 'docker logout' followed by 'docker login'


Login Succeeded
➜  mcp-gateway git:(main) docker mcp gateway run --profile profile
- Reading profile configuration...
  - Loading 2 catalog(s) for dynamic tools
    - Processing catalog 'docker/mcp-catalog-dhi:latest' with 11 servers
    - Processing catalog 'roberthouse224/our-catalog:latest' with 7 servers
  - Total servers loaded from all catalogs: 18
- Configuration read in 90.553083ms
- Using images:
  - dhi.io/context7-mcp:latest
  - mcp/playwright@sha256:082a1c37208cdcb216aee6943f8d8bbe23f1c59d827b2101e1f06e6f778cc105
> Images pulled in 10.233647583s
- Those servers are enabled: playwright, context7-mcp
- Listing MCP tools...
  - Running mcp/playwright with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=playwright -l docker-mcp-transport=stdio]
  - Running dhi.io/context7-mcp:latest with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=context7-mcp -l docker-mcp-transport=stdio -e MCP_TRANSPORT]
  > playwright: (21 tools)```

@bobbyhouse
Copy link
Copy Markdown
Contributor

question: again I may just be having environment issues. Been a while since I've run the regular DD gateway, but I can't seem to get cursor to load with a profile that has DHI images in it.

Screenshot 2026-03-26 at 12 29 39 PM

@jchangx
Copy link
Copy Markdown
Contributor Author

jchangx commented Mar 26, 2026

question: this experience have something to do with these changes? Seems odd because it appear to work fine for dhi, but I get some kind of auth related issue for the docker mcp catalog?

➜  mcp-gateway git:(main) docker mcp gateway run --profile profile
- Reading profile configuration...
  - Loading 2 catalog(s) for dynamic tools
    - Processing catalog 'docker/mcp-catalog-dhi:latest' with 11 servers
    - Processing catalog 'roberthouse224/our-catalog:latest' with 7 servers
  - Total servers loaded from all catalogs: 18
- Configuration read in 79.807625ms
- Using images:
  - dhi.io/context7-mcp:latest
  - mcp/playwright@sha256:082a1c37208cdcb216aee6943f8d8bbe23f1c59d827b2101e1f06e6f778cc105
  - warning: pulling docker image mcp/playwright@sha256:082a1c37208cdcb216aee6943f8d8bbe23f1c59d827b2101e1f06e6f778cc105: Error response from daemon: authentication required - incorrect username or password> Images pulled in 524.564083ms
- Those servers are enabled: playwright, context7-mcp
- Listing MCP tools...
  - Running dhi.io/context7-mcp:latest with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=context7-mcp -l docker-mcp-transport=stdio -e MCP_TRANSPORT]
  - Running mcp/playwright with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=playwright -l docker-mcp-transport=stdio]
  > Can't start playwright: failed to connect: calling "initialize": EOF
^C  > Can't start context7-mcp: failed to connect: context canceled
> 0 tools listed in 27.118061666s
- Adding internal tools (dynamic-tools feature enabled)
  > mcp-find: tool for finding MCP servers in the catalog
  > mcp-add: tool for adding MCP servers to the registry
  > mcp-remove: tool for removing MCP servers from the registry
  > code-mode: write code that calls other MCPs directly
  > mcp-exec: execute tools that exist in the current session
  > mcp-config-set: tool for setting configuration values for MCP servers
  > mcp-create-profile: tool for creating or updating profiles with current gateway state
  > mcp-activate-profile: tool for activating saved profiles
  > mcp-discover: prompt for learning about dynamic server management
docker Desktop is not running: Docker Desktop is not running
➜  mcp-gateway git:(main) docker login
Authenticating with existing credentials... [Username: roberthouse224]

i Info → To login with a different account, run 'docker logout' followed by 'docker login'


Login Succeeded
➜  mcp-gateway git:(main) docker mcp gateway run --profile profile
- Reading profile configuration...
  - Loading 2 catalog(s) for dynamic tools
    - Processing catalog 'docker/mcp-catalog-dhi:latest' with 11 servers
    - Processing catalog 'roberthouse224/our-catalog:latest' with 7 servers
  - Total servers loaded from all catalogs: 18
- Configuration read in 90.553083ms
- Using images:
  - dhi.io/context7-mcp:latest
  - mcp/playwright@sha256:082a1c37208cdcb216aee6943f8d8bbe23f1c59d827b2101e1f06e6f778cc105
> Images pulled in 10.233647583s
- Those servers are enabled: playwright, context7-mcp
- Listing MCP tools...
  - Running mcp/playwright with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=playwright -l docker-mcp-transport=stdio]
  - Running dhi.io/context7-mcp:latest with [run --rm -i --init --security-opt no-new-privileges --cpus 1 --memory 2Gb --pull never -l docker-mcp=true -l docker-mcp-tool-type=mcp -l docker-mcp-name=context7-mcp -l docker-mcp-transport=stdio -e MCP_TRANSPORT]
  > playwright: (21 tools)```

Hmm, this change shouldn't impact the existing docker.io path at all since we just branch off. Given that pulling mcp/... worked after docker login, maybe you had some stale auth?

@jchangx jchangx merged commit 2e0af0e into docker:main Mar 30, 2026
5 checks passed
@jchangx jchangx deleted the fix/dhi-registry-auth branch March 30, 2026 21:23
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.

2 participants