Registry Token Service Operations
Operating the Stella Ops registry token service: issuing short-lived Docker registry bearer tokens gated on Authority tokens and plan entitlements.
Audience: Operators deploying and monitoring the registry token service, and integrators wiring Docker/OCI clients to a Stella Ops-fronted registry.
Component: src/Registry/StellaOps.Registry.TokenService
The registry token service issues short-lived Docker registry bearer tokens after validating an Authority OpTok (DPoP/mTLS sender constraint) and the customer’s plan entitlements. It is fronted by the Docker registry’s Bearer realm flow. For the broader registry design and how this service fits in, see the Registry module overview and architecture.
Configuration
Configuration lives in etc/registry-token.yaml and can be overridden through environment variables prefixed with REGISTRY_TOKEN_. Key sections:
| Section | Purpose |
|---|---|
authority | Authority issuer/metadata URL, audience list, and scopes required to request tokens (default registry.token.issue). |
signing | JWT issuer, signing key (PEM or PFX), optional key ID, and token lifetime (default five minutes). The repository ships etc/registry-signing-sample.pemfor local testing only – replace it with a private key generated and stored per-environment before going live. |
registry | Registry realm URL and optional allow-list of service values accepted from the registry challenge. |
plans | Plan catalogue mapping plan name → repository patterns and allowed actions. Wildcards (*) are supported per path segment. |
defaultPlan | Applied when the caller’s token omits stellaops:plan. |
revokedLicenses | Blocks issuance when the caller presents a matching stellaops:license claim. |
Plan entries must cover every private repository namespace. Actions default to pull if omitted.
Request flow
- Docker/OCI client contacts the registry and receives a
401withWWW-Authenticate: Bearer realm=...,service=...,scope=repository:.... - Client acquires an OpTok from Authority (DPoP/mTLS bound) with the
registry.token.issuescope. - Client calls
GET /token?service=<service>&scope=repository:<name>:<actions>against the token service, presenting the OpTok and matching DPoP proof. - The service validates the token, plan, and requested scopes, then issues a JWT containing an
accessclaim conforming to the Docker registry spec.
All denial paths return RFC 6750-style problem responses (HTTP 400 for malformed scopes, 403 for plan or revocation failures).
Monitoring
The service emits OpenTelemetry metrics via registry_token_issued_total and registry_token_rejected_total. Suggested Prometheus alerts:
| Metric | Condition | Action |
|---|---|---|
registry_token_rejected_total | increase(...) > 0 over 5 minutes | Investigate plan misconfiguration or licence revocation. |
registry_token_issued_total | Sudden drop compared to baseline | Confirm registry is still challenging with the expected realm/service. |
Enable the built-in /healthz endpoint for liveness checks. Authentication and DPoP failures surface via the service logs (Serilog console output).
Sample deployment
dotnet run --project src/Registry/StellaOps.Registry.TokenService \
--urls "http://0.0.0.0:8085"
curl -H "Authorization: Bearer <OpTok>" \
-H "DPoP: $(dpop-proof ...)" \
"http://localhost:8085/token?service=registry.localhost&scope=repository:stella-ops/public/base:pull"
Replace <OpTok> and DPoP with tokens issued by Authority. The response contains token, expires_in, and issued_at fields suitable for Docker/OCI clients.
