Registry token
Operations of the License API. Paths are relative to your deployment's API host.
GET /api/license-api/.well-known/jwks.json
Publish the RSA verification key(s) for the OCI registry token.
Public, unauthenticated and cacheable. NOT the license key — see /.well-known/xema-license-keys.json for the Ed25519 key that verifies a LICENSE. The registry consumes a materialised copy of this document from a mounted Secret rather than fetching this URL. Several keys may appear at once: that overlap IS the rotation mechanism, and the key currently being signed with is always the first entry.
Authentication: none
| Status | Description | Body |
|---|---|---|
| 200 | application/json RegistryJwksDto | |
| 400 | application/problem+json ProblemDetailsDto | |
| 401 | application/problem+json ProblemDetailsDto | |
| 403 | application/problem+json ProblemDetailsDto | |
| 404 | application/problem+json ProblemDetailsDto | |
| 409 | application/problem+json ProblemDetailsDto | |
| 422 | application/problem+json ProblemDetailsDto | |
| 500 | application/problem+json ProblemDetailsDto |
GET /api/license-api/v2/token
Exchange a Xema license for a short-lived, repository-scoped registry token.
Implements the OCI/Distribution token specification. The license is presented as HTTP Basic with the JWS in the PASSWORD field (what docker, podman, helm, skopeo and containerd actually send; the username is conventional and is ignored) or as Bearer for programmatic callers. A PARTIAL grant is a success: asking for pull,push and receiving pull is the specified behaviour, and the registry denies the push itself. offline_token=true with no scope is a docker login probe and returns 200 with an empty access array.
Authentication: none
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
account | query | any | no | The username the client typed. ADVISORY ONLY — attacker-controlled, so it never influences the entitlement decision. Used for the sub of an anonymous probe and for audit. |
client_id | query | any | no | Sent by docker (client_id=docker). Ignored. |
offline_token | query | any | no | docker login sends true with no scope. Answered 200 with an empty grant — an error here makes docker login fail outright and the user concludes their license is bad. |
scope | query | array of any | no | repository:<name>:<actions>, REPEATABLE. Distribution sends several in one request during a cross-repo blob mount, so handling only the first would silently degrade mounts into full layer re-uploads. A malformed scope is DISCARDED, never fatal — a 500 here would turn a client bug into an outage. registry:catalog:* is never granted, because /v2/_catalog enumerates every repository on the registry. |
service | query | any | yes | Must equal the configured registry service. This is the AUDIENCE binding — accepting an arbitrary value would let a token minted here be replayed against a different registry that trusts the same JWKS. A mismatch is a 400. |
| Status | Description | Body |
|---|---|---|
| 200 | application/json RegistryTokenResponseDto | |
| 400 | application/problem+json ProblemDetailsDto | |
| 401 | application/problem+json ProblemDetailsDto | |
| 403 | application/problem+json ProblemDetailsDto | |
| 404 | application/problem+json ProblemDetailsDto | |
| 409 | application/problem+json ProblemDetailsDto | |
| 422 | application/problem+json ProblemDetailsDto | |
| 500 | application/problem+json ProblemDetailsDto |