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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions