Skip to content

Conversation

@LaurentGoderre
Copy link
Contributor

What does this PR do?

When doing a Docker pull on an image with the default registry docker.io, the auth helper doesn't match the image to the authentication data stored by the engine under https://index.docker.io/v1 causing the error: credentials not found in native keychain

Why is it important?

This is important to support the default registry prefix.

How to test this PR

Unit test added

@LaurentGoderre LaurentGoderre requested a review from a team as a code owner November 3, 2025 15:41
@netlify
Copy link

netlify bot commented Nov 3, 2025

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit df49f93
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/6908d3e35c049a00083e4f95
😎 Deploy Preview https://deploy-preview-3482--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

Summary by CodeRabbit

  • Bug Fixes
    • Fixed Docker image authentication to properly use the default registry configuration when pulling images from docker.io, ensuring correct credentials are applied during the authentication process.

Walkthrough

Docker image authentication logic now remaps images with the docker.io host to the configured default registry before performing credential lookup. A new test verifies that DockerImageAuth returns credentials matching the default registry for a docker.io image.

Changes

Cohort / File(s) Summary
Docker auth implementation
docker_auth.go
Remap docker.io image host to the configured default registry prior to credential lookup so credentials are resolved against the default registry config.
Docker authentication tests
docker_auth_test.go
Added sub-test "match the default registry authentication by host" in TestDockerImageAuth that sets a default registry, injects credentials, calls DockerImageAuth for docker.io/my/image:latest, and asserts registry, username, password, and encoded Auth.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant AuthLayer as Auth Resolver
    participant CredStore as Credential Store

    rect rgb(235,248,255)
    Client->>AuthLayer: Request auth for image "docker.io/my/image:latest"
    note right of AuthLayer: New step: remap docker.io -> defaultRegistry()
    AuthLayer->>AuthLayer: if host == "docker.io" then host = defaultRegistry()
    end
    AuthLayer->>CredStore: Lookup credentials for remapped host
    CredStore-->>AuthLayer: Credentials (username, password, auth)
    AuthLayer-->>Client: Return registry, username, password, encoded Auth
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Inspect docker_auth.go remapping logic for edge cases (empty/default registry, trailing slashes, host normalization).
  • Validate tests in docker_auth_test.go properly set and restore global/default registry state and credential mocks.
  • Confirm base64/encoding of Auth and comparison expectations match production encoding code paths.

Poem

🐰 I hopped from host to host, a tiny sleuth,
docker.io turned home to the registry truth,
I fetched the creds, encoded each part,
A cheerful auth check — a rabbit's smart heart. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'fix: docker auth for docker.io images' directly summarizes the main change in the changeset. The title clearly identifies that this is a fix for Docker authentication when pulling images from docker.io, which aligns perfectly with the code changes that remap docker.io to the default registry in the authentication lookup logic and add a corresponding test case.
Description check ✅ Passed The pull request description is directly related to the changeset. It clearly explains the problem being addressed (Docker auth helper not matching docker.io images to credentials stored under https://index.docker.io/v1), the importance (supporting the default registry prefix), and notes that a unit test was added. This aligns well with the code changes that fix the authentication remapping logic and add a test case.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@LaurentGoderre LaurentGoderre changed the title fix docker auth for docker.io images fix: docker auth for docker.io images Nov 3, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf4458c and df49f93.

📒 Files selected for processing (2)
  • docker_auth.go (1 hunks)
  • docker_auth_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker_auth_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: lint (modules/dynamodb) / lint: modules/dynamodb
  • GitHub Check: lint (modulegen) / lint: modulegen
  • GitHub Check: lint (modules/dind) / lint: modules/dind
  • GitHub Check: lint (modules/registry) / lint: modules/registry
  • GitHub Check: lint (modules/dockermodelrunner) / lint: modules/dockermodelrunner
  • GitHub Check: lint (modules/postgres) / lint: modules/postgres
  • GitHub Check: lint (modules/qdrant) / lint: modules/qdrant
  • GitHub Check: lint (modules/pinecone) / lint: modules/pinecone
  • GitHub Check: lint (modules/redpanda) / lint: modules/redpanda
  • GitHub Check: lint (modules/solace) / lint: modules/solace
  • GitHub Check: lint (modules/memcached) / lint: modules/memcached
  • GitHub Check: lint (modules/openfga) / lint: modules/openfga
  • GitHub Check: lint (modules/pulsar) / lint: modules/pulsar
  • GitHub Check: lint (modules/artemis) / lint: modules/artemis
  • GitHub Check: lint (modules/influxdb) / lint: modules/influxdb
  • GitHub Check: lint (modules/rabbitmq) / lint: modules/rabbitmq
  • GitHub Check: lint (modules/dolt) / lint: modules/dolt
  • GitHub Check: lint (modules/mariadb) / lint: modules/mariadb
  • GitHub Check: lint (modules/consul) / lint: modules/consul
  • GitHub Check: Analyze (go)

Comment on lines +45 to +47
if reg == "docker.io" {
reg = defaultRegistry
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Fix correctly remaps docker.io to canonical registry address.

The remapping ensures credential lookup uses the canonical registry address (https://index.docker.io/v1) where Docker stores authentication data, addressing the stated issue.

Please verify the following edge cases:

  1. Case sensitivity: Should the comparison be case-insensitive? Docker registries treat hostnames as case-insensitive.
  2. Other Docker registry aliases: Does registry-1.docker.io or other aliases require similar remapping?

Consider extracting the hardcoded string to a constant for better maintainability:

+const dockerIORegistry = "docker.io"
+
 func dockerImageAuth(ctx context.Context, image string, configs map[string]registry.AuthConfig) (string, registry.AuthConfig, error) {
 	defaultRegistry := defaultRegistryFn(ctx)
 	reg := core.ExtractRegistry(image, defaultRegistry)
 
-	if reg == "docker.io" {
+	if reg == dockerIORegistry {
 		reg = defaultRegistry
 	}

🏁 Script executed:

#!/bin/bash
# Verify if core.ExtractRegistry normalizes case and check for other registry aliases

echo "=== Searching for registry extraction logic ==="
rg -n -C5 'func ExtractRegistry' 

echo -e "\n=== Searching for other docker.io references ==="
rg -n -C3 'docker\.io|registry-1\.docker\.io' --type go -g '!*_test.go'

echo -e "\n=== Checking for registry-related constants ==="
rg -n -C3 'const.*[Rr]egistry|IndexDockerIO' --type go

Length of output: 7590


Now I need to check the actual implementation of ExtractRegistry and see if there are test cases demonstrating the expected behavior.


🏁 Script executed:

#!/bin/bash
# Check full ExtractRegistry implementation
echo "=== ExtractRegistry full implementation ==="
sed -n '95,120p' internal/core/images.go

echo -e "\n=== Check how dockerImageAuth is tested with different registry cases ==="
rg -n -A 10 -B 2 'dockerImageAuth' docker_auth_test.go | head -60

echo -e "\n=== Search for test cases with case variations ==="
rg -n 'docker\.io|Docker\.IO' docker_auth_test.go internal/core/images_test.go

Length of output: 1274


Fix addresses docker.io remapping but has exploitable gaps that need addressing.

The remapping correctly uses the canonical registry for credential lookup. However, the current implementation has two issues:

  1. Case sensitivity: The comparison reg == "docker.io" is case-sensitive, so images using mixed case (e.g., Docker.io/myimage) won't be remapped. Since ExtractRegistry doesn't normalize case, this could cause credential lookups to fail for such images.

  2. Incomplete alias coverage: The code only handles docker.io, but registry.hub.docker.com (visible in options.go:233) is another Docker Hub alias that should receive the same treatment.

Recommended fixes:

// Make comparison case-insensitive and handle both aliases
if strings.EqualFold(reg, "docker.io") || strings.EqualFold(reg, "registry.hub.docker.com") {
    reg = defaultRegistry
}

Or, consider normalizing registry names consistently in ExtractRegistry by using strings.ToLower().

🤖 Prompt for AI Agents
In docker_auth.go around lines 45 to 47, the remapping only checks for the
literal "docker.io" which is case-sensitive and misses the alias
registry.hub.docker.com; update the check to treat registry names
case-insensitively and include both aliases (e.g., use strings.EqualFold for
"docker.io" and "registry.hub.docker.com") or normalize registry names with
strings.ToLower earlier (such as in ExtractRegistry) so both mixed-case names
and the hub alias are remapped to defaultRegistry.

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