CDS HTTP API

Every endpoint the Certificate Distribution Service serves — attestation and certificate issuance, CA handoff, the image allowlist CRUD surface, and the discovery routes — with method, path, authorization, and response codes.

The CDS (Certificate Distribution Service) serves one HTTP API over RA-TLS on port 8443. Every flag that configures it is in the CLI reference.

Attestation and issuance

MethodPathAuthPurpose
POST/authenticatenoneissue a one-time challenge nonce (--challenge-ttl, default 60s)
POST/attestchallenge + evidenceverify evidence (and an optional sandbox token) and sign a CSR, returning the leaf PEM chain
POST/attest-keychallenge + evidenceverify evidence and issue an EAR bound to the caller's key
POST/sign-csrEARsign a CSR for a caller that already holds an EAR bound to the CSR key
POST/handoffEARhand the mesh CA and allowlist snapshot to an attested peer replica; mounted only with --handoff-measurements

Allowlist

MethodPathAuthPurpose
GET/allowlistnonethe whole document as canonical JSON; returns a weak ETag W/"<version>" and honors If-None-Match (304 when unchanged)
PUT/allowlistoperator tokenreplace floor and workloads atomically; the CDS assigns the new version; 204
POST/allowlist/digestsoperator tokenadd one floor entry { digest, image }; 204
DELETE/allowlist/digestsoperator tokendelete { digests: [...] } atomically — all-or-nothing, 404 if any is missing
PUT/allowlist/workloads/<name>operator tokencreate or replace one workload entry, whole; 204
DELETE/allowlist/workloads/<name>operator tokendelete one workload entry; 404 if absent

A missing or invalid operator token is 401; a body the CDS cannot parse or validate is 422. Writes carry their own 1 MiB body cap, independent of the --max-request-size that bounds the attestation endpoints.

Enforcers poll GET /allowlist and use the ETag to avoid redundant work — the version only changes when the set actually changes (nriImagePolicy.refresh.interval, default 30s).

Secrets

MethodPathAuthPurpose
GET/secrets/<path>mesh leaf + sandbox tokenread a released value; 404 when the path is ungranted or absent
POST/secrets/<path>mesh leaf + sandbox tokenmint and store 32 random bytes at an empty path; 409 when another caller won the race
PUT/secrets/<path>operator tokenstore an operator-supplied value; create-only unless the caller asked to overwrite

Denials are deliberately opaque — an ungranted path is indistinguishable from a missing one, so the API cannot enumerate the store. The reason goes to the CDS log. Workload routes are rate-limited per sandbox, keyed on the ID in the verified client certificate.

The CDS declines to serve /secrets at all when --ratls-platform, --measurements, or --sandbox-inventory-cidr is missing, or when CA handoff is configured. See Application secrets.

Discovery

MethodPathAuthPurpose
GET/operator-keysnonethe pinned operator public-key PEM bundle; 404 when allowlist writes are disabled
GET/.well-known/jwks.jsonnonethe EAR-signing JWKS (ES256)
GET/canonethe mesh CA bundle
GET/readyznonereadiness; fails if the attestation-api is unhealthy, or CA validity is below --min-ca-validity

Operator tokens

Every allowlist and operator-supplied secret write carries a JWT signed with the operator's ECDSA key (ES256, ES384, or ES512, matching the key's curve), minted fresh per request with a 60-second lifetime. Three claims bind it to that one write:

ClaimBinds
pbhSHA-256 of the exact request body
htmthe HTTP method
htuthe URL path

The CDS accepts a mutation only when the signature verifies against a pinned key, exp − iat is at most five minutes (a server-side cap), the method and path match the request being handled, and the body hash matches a re-hash of the body actually received, compared in constant time. See Authorizing mutations for the trust boundaries of this design, and Manage the allowlist for the CLI that mints them.