Skip to content

docker_registry credentials for public.ecr.aws fail with 400 (Your Authorization Token is invalid) #157

Description

@SharpEdgeMarshall

Summary

Dependabot fails to authenticate with Amazon ECR Public (public.ecr.aws) when configured
as a docker_registry private registry. The proxy sends Authorization: Basic, but ECR
Public only accepts Authorization: Bearer and responds with HTTP 400 (not 401) for
any Basic auth request (not on the /token endpoint):

{"errors":[{"code":"DENIED","message":"Your Authorization Token is invalid."}]}

Because the response is 400 and not 401, TokenTransport.isTokenDemand() never
triggers, so the token exchange flow is never attempted. (Ref: https://github.com/stackrox/docker-registry-client/blob/main/registry/tokentransport.go#L141)

Not being able to authenticate on public.ecr.aws causes 429 ratelimit errors during dependabot execution.

Root Cause

In internal/handlers/docker_registry.go, the ecrRe regex only matches private ECR
hostnames (\d+.dkr.ecr.*\.amazonaws\.com). public.ecr.aws does not match, so it falls
through to the generic BasicTransport path:

// line 26 — public.ecr.aws does NOT match this
ecrRe = regexp.MustCompile(`\A\d+.dkr.ecr.([a-z0-9-]+)\.amazonaws\.com\z`)

// line 121-136 — public.ecr.aws ends up here
transport := &registry.BasicTransport{
    Transport: &registry.TokenTransport{...},
    URL:       fmt.Sprintf("https://%s", cred.registry),
    Username:  cred.getUsername(),   // e.g. "AWS"
    Password:  cred.getPassword(),   // e.g. <jwt>
}

BasicTransport.RoundTrip unconditionally adds Authorization: Basic base64("AWS:")
to every request (it only skips auth if both username and password are empty strings).

ECR Public's behaviour differs from private ECR:

  • Private ECR (.dkr.ecr..amazonaws.com) — returns 401 on wrong auth →
    TokenTransport kicks in → works
  • ECR Public (public.ecr.aws) — returns 400 on any Basic auth → transport chain
    never retries → broken

Expected / Required Auth Flow for ECR Public

Per the ECR Public authentication docs,
the correct auth for public.ecr.aws registry endpoints is:

Authorization: Bearer <base64("AWS:")>

where the token is obtained from ecr-public:GetAuthorizationToken (us-east-1 only).

Suggested Fix

Extend getECRCredentials to also handle public.ecr.aws as a special case and then call
helpers.SetBearerAuthorization instead of helpers.SetBasicAuthorization:

Environment

  • Registry: public.ecr.aws (Amazon ECR Public)
  • Configured via GitHub org private registry API as docker_registry type

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions