Conversation
Allow keys in the "credHelpers" and "auths" sections of the CLI config file to be wildcard patterns, such as "*.dkr.ecr.*.amazonaws.com" or "*.docker.artifactory.example.com", so that a single entry can be used for registries that encode an account, region, or project in their hostname. A "*" matches any sequence of characters within a single hostname label, and never matches a ".". The last two labels of a pattern must not contain a wildcard, so that patterns such as "*.com" cannot be used to send credentials to an overly broad set of registries. Exact matches always take precedence over patterns. If multiple patterns match, the most specific one (the one with the most non-wildcard characters) is used, and ties are broken by lexical order to make the result deterministic. Wildcard patterns in "credHelpers" are skipped by GetAllCredentials, as they are not registry hostnames that can be looked up in the helper. Signed-off-by: Yannik Tausch <dev@ytausch.de>
Instead of silently ignoring keys in the "auths" and "credHelpers" sections that contain a "*" wildcard but are not valid patterns (for example, "*.com", "foo.*.com", or "https://*.example.com"), return an error from ConfigFile.LoadFromReader that lists each invalid key. The docker CLI prints this error as a warning when loading the config file, as it does for other config errors; invalid patterns are never used for matching. Signed-off-by: Yannik Tausch <dev@ytausch.de>
ytausch
marked this pull request as ready for review
September 23, 2026 17:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Allow keys in the
credHelpersandauthssections ofconfig.jsonto be wildcard patterns, so a single entry covers registries that encode an account, region, project, or channel in the hostname:{ "credHelpers": { "*.dkr.ecr.*.amazonaws.com": "ecr-login", "*-docker.pkg.dev": "gcloud" }, "auths": { "*.docker.artifactory.example.com": { "auth": "..." } } }My own use case is the
authsone: our Artifactory instance serves each channel on its own subdomain (<channel>.docker.artifactory.example.com), and today I have todocker loginto every channel separately.Matching rules
*matches any sequence of characters within a single label and never matches a.. The pattern and the host must have the same number of labels, soabc.*.def.example.commatchesabc.x.def.example.combut notabc.x.y.def.example.com, and*.example.comdoes not matchexample.com. A*can also be part of a label (*-docker.pkg.dev).*.example.comdoes not matchfoo.example.com:5000, but*.example.com:5000does.co.uk(so*.co.ukis accepted), and choosing sensible patterns is ultimately the user's responsibility.*.example.com/team) could never mean what it appears to. A scheme isn't needed; wildcard keys are written by hand and never come from the legacyhttps://hostkeys that olddocker loginversions wrote.authsorcredHelperskey containing a*that isn't a valid pattern makesConfigFile.LoadFromReaderreturn an error listing each offending key, for example:LoadDefaultConfigFile, which (as for any other config error) prints this warning and continues; the invalid entries are never used for matching. Library consumers callingconfig.Load/LoadFromReaderget the error.*is special. I deliberately didn't usepath.Match/filepath.Match: they also treat?,[and\as special characters, and[appears in IPv6 literals such as[::1]:5000.*are not validated or changed in any way, so the Docker Hub key (https://index.docker.io/v1/) and legacy URL keys are unaffected.Precedence
credHelpersentrycredHelperspatterncredsStoreauthspattern"Most specific" means the pattern with the most non-wildcard characters. Ties are broken by lexical order so the result is deterministic despite map iteration order.
When an
authspattern matches, the returnedAuthConfig.ServerAddressis the requested host, not the pattern.GetAllCredentialsskips wildcardcredHelperskeys. Without that, it would invoke the helper with the literal pattern (e.g.docker-credential-ecr-login getfor*.dkr.ecr.*.amazonaws.com).Implementation
cli/config/internal/hostmatch(Validate,IsPattern,Match,Best). It's internal so this doesn't add public API;cli/configonly imports its own sub-packages, and this keeps it that way.credentials.fileStore.Getfalls back to the best matchingauthspattern.configfile.getConfiguredCredentialStorefalls back to the best matchingcredHelperspattern.configfile.LoadFromReadervalidates allauthsandcredHelperskeys containing a*.docs/reference/commandline/login.md.Compatibility
*, so no existing working entry changes meaning, and exact matches always win. Wildcard keys already exist in the wild, though: kubelet has long supported them in image pull secrets, with the same per-label semantics. Configs like that, reused as a~/.docker/config.json(e.g. in CI), will start matching. Such configs that use patterns this PR considers invalid (e.g.*.com, or a scheme likehttps://*.example.com, which kubelet accepts) will now produce a config-parsing warning in the docker CLI and an error forconfig.Loadcallers, where the key was previously ignored silently.cli/config(go-containerregistry/crane, buildx, compose, nerdctl): they ignore pattern keys during lookup. ForcredHelperspatterns, an olderGetAllCredentialslogs a warning after the helper fails for the literal pattern.authspatterns are ignored on lookup.credHelperspatterns are the rough edge: itsGetAllCredentialscalls the helper with the literal pattern and returns an error if the helper fails. That's something to be aware of when sharing a config with those tools.Open questions for reviewers
authspatterns created?docker loginmust authenticate against a real host, sodocker login '*.example.com'can't work. For now the documented workflow is: log in to one registry, then rename its key to the pattern. A follow-up could add a way fordocker loginto store under a pattern.docker login foo.example.comauthenticates with the matched credentials and then stores them under the exact keyfoo.example.com. That exact entry then shadows the pattern, e.g. after a password rotation. Is that acceptable, or should login write back to the matching pattern?docker logout foo.example.comonly erases exact entries, so credentials matched through a pattern stay in place. Should logout mention that?*.com) are rejected when the config is loaded (see above). Is failingLoadFromReaderthe right level, given thatconfig.Loadcallers get a hard error? The alternative would be to only warn in the CLI.DOCKER_AUTH_CONFIG(memorystore) doesn't support patterns in this PR.Testing
Validate,Match,Best), for the file store (TestFileStoreGetWildcard), and for the config file (TestGetConfiguredCredentialStoreWildcard,TestGetAllCredentialsSkipsWildcardCredHelpers,TestLoadFromReaderInvalidRegistryPatterns,TestLoadFromReaderValidRegistryPatterns). I checked that the matching tests fail without the source changes.*.docker.localhost:5055inauths,docker login channel-a.docker.localhost:5055reports "Authenticating with existing credentials... [Username: ytausch]", whilex.y.docker.localhost:5055finds no credentials. Adding*.comandfoo.*.comentries prints the warning shown above.Release notes (optional)
AI Note
I was assisted by Claude Code (Opus 5.5) in creating this PR but also did a manual pass-through.