diff --git a/nginx.conf b/nginx.conf index 4bd6f90..b0c740b 100644 --- a/nginx.conf +++ b/nginx.conf @@ -100,15 +100,21 @@ http { default ""; } - # @TODO: actually for auth.docker.io, if we want to support multiple authentications, we'll need to decide - # @TODO: based not only on the hostname, but also URI (/token) and query string (?scope) - # @TODO: I wonder if this would help gcr.io and quay.io with authentication also.... - - map $dockerAuth $finalAuth { - "" "$http_authorization"; # if empty, keep the original passed-in from the docker client. - default "Basic $dockerAuth"; # if not empty, add the Basic preamble to the auth + # First, build what we would inject from configured registry credentials (empty if none configured). + map $dockerAuth $injectedAuth { + "" ""; + default "Basic $dockerAuth"; } + # Then prefer the Docker client's own auth header (bearer or basic it negotiated itself) + # and only fall back to injecting our basic credentials when the client has nothing. + # This fixes registries like quay.io that use bearer tokens for blob/manifest endpoints: + # without this, the proxy would overwrite the client's bearer token with basic credentials, + # causing 401s on the actual content fetch after authentication succeeded. + map $http_authorization $finalAuth { + ~\S $http_authorization; # client has auth (bearer or basic) — pass it through + default $injectedAuth; # client has nothing — inject our basic credentials + } # Map to decide which hosts get directed to the caching portion. # This is automatically generated from the list of cached registries, plus a few fixed hosts