Auth Flow
Overview
Section titled “Overview”trupu implements the OpenSSF Trusted Publishers pattern for Docker registries, similar to how npm, PyPI, and RubyGems handle trusted publishing.
Step-by-step flow
Section titled “Step-by-step flow”1. GitHub Actions requests an OIDC token
Section titled “1. GitHub Actions requests an OIDC token”The workflow uses the id-token: write permission to request a short-lived JWT from GitHub’s OIDC provider (https://token.actions.githubusercontent.com).
The token contains claims like:
{ "iss": "https://token.actions.githubusercontent.com", "aud": "https://registry.example.com", "repository": "my-org/my-app", "ref": "refs/heads/main", "job_workflow_ref": "my-org/my-app/.github/workflows/publish.yml@refs/heads/main"}2. Docker sends credentials
Section titled “2. Docker sends credentials”The workflow passes the OIDC token as the password in docker login. Docker encodes it as Basic auth (oauth2:<token>) and sends it with every push request.
3. Traefik forwards to trupu
Section titled “3. Traefik forwards to trupu”Traefik’s ForwardAuth middleware intercepts every request to /v2/* and sends a GET to http://trupu:3000/auth with the original headers.
4. trupu verifies the token
Section titled “4. trupu verifies the token”trupu:
- Extracts the token from the
Authorizationheader (supports both Basic and Bearer) - Verifies the JWT signature against GitHub’s JWKS (
https://token.actions.githubusercontent.com/.well-known/jwks) - Validates the
iss(issuer) andaud(audience) claims - Extracts
repositoryandworkflowfrom the token claims - Checks if
repository:workflowmatches an entry inALLOWED_PUBLISHERS - Optionally checks the
refclaim againstALLOWED_REFS
5. Request is proxied or rejected
Section titled “5. Request is proxied or rejected”- 200 — auth succeeded, Traefik proxies the request to the Docker registry
- 401 — no credentials provided, returns
Www-Authenticate: Basic realm="trupu" - 403 — token invalid or publisher not trusted
Response headers
Section titled “Response headers”On successful authentication, trupu sets these headers (forwarded by Traefik to the registry):
| Header | Example | Description |
|---|---|---|
X-Trupu-Repository | my-org/my-app | The GitHub repository |
X-Trupu-Workflow | publish.yml | The workflow filename |
X-Trupu-Ref | refs/heads/main | The git ref |