Authority Revocation Bundle

Audience: Authority operators, Offline Kit / air-gap mirror maintainers, integrators consuming revocations. Scope: The on-disk revocation bundle format, its deterministic formatting and signing rules, and the CLI/API surface for exporting and verifying it.

The Authority service exports revocation information as an offline-friendly JSON document plus a detached JWS signature. Operators can mirror the bundle alongside Concelier exports so that air-gapped scanners receive the latest token, subject, and client revocations during the same sync pass.

File layout

ArtefactDescription
revocation-bundle.jsonCanonical JSON document describing revoked entities. Validates against etc/authority/revocation_bundle.schema.json.
revocation-bundle.json.jwsDetached JWS signature covering the exact UTF-8 bytes of revocation-bundle.json.
revocation-bundle.json.sha256SHA-256 digest used by mirror automation. The CLI auth revoke export writes it in prefixed sha256:<hex> form (lower-case hex). Optional but recommended.

All hashes and signatures are generated after applying the deterministic formatting rules below.

Deterministic formatting rules

Consumers MUST treat the combination of schemaVersion and sequence as a monotonic feed. Bundles with older sequence values are ignored unless bundleId differs and issuedAt is newer (supporting replay detection).

Revocation entry categories

The schema (revocation_bundle.schema.json) enumerates four categories. Two are emitted by the current builder; the other two are reserved by the schema for forward-looking use but are not produced by any Authority code path today.

CategoryStatusDescriptionRequired fields (per schema)
tokenEmitted (RevocationBundleBuilder.BuildTokenEntries, from revoked token documents)A single OAuth token (access, refresh, device, authorization code).tokenType, clientId (plus id, revokedAt); optional subjectId
clientEmitted (StandardClientProvisioningStore / LdapClientProvisioningStore write manual client revocations)Entire OAuth client registration is revoked.clientId (plus id, revokedAt)
subjectSchema-reserved (no current emitter)All credentials issued to a subject (user/service account).subjectId (plus id, revokedAt)
keySchema-reserved (no current emitter; the schema declares no key-specific then clause)Signing/encryption key material revoked.id, revokedAt

reason is a machine-friendly code constrained to the schema pattern ^[a-z0-9_.-]{1,64}$ (lower-cased on export); observed values include compromised, rotation, and lifecycle. When the source revocation has no reason recorded, the builder emits unspecified. reasonDescription may include a short operator note (max 256 chars).

Detached JWS workflow

  1. Serialise revocation-bundle.json using the deterministic rules.
  2. Compute the lower-case hex SHA-256 digest of the canonical bytes; write it to revocation-bundle.json.sha256 (the CLI prefixes it as sha256:<hex>).
  3. Sign using ES256 (default, or Signing.Algorithm when overridden) with the configured Authority signing key (Signing.ActiveKeyId). The detached JWS header carries the following claims (serialised compactly by the signer; shown expanded here for readability):
    {
      "alg": "ES256",
      "kid": "{signingKeyId}",
      "provider": "{providerName}",
      "typ": "application/vnd.stellaops.revocation-bundle+jws",
      "b64": false,
      "crit": ["b64"]
    }
    
  4. Persist the detached signature payload to revocation-bundle.json.jws (per RFC 7797).

Verification steps:

  1. Validate revocation-bundle.json against the schema.
  2. Re-compute SHA-256 and compare with .sha256 (if present).
  3. Resolve the signing key from the Authority JWKS endpoint (/jwks, advertised in /.well-known/openid-configuration) or the offline key bundle, preferring the provider declared in the JWS header (provider falls back to default).
  4. Verify the detached JWS using the resolved provider. The CLI mirrors Authority resolution, so builds compiled with StellaOpsCryptoSodium=true automatically use the libsodium provider when advertised; otherwise verification downgrades to the managed fallback.

CLI verification workflow

Use the bundled CLI command before distributing a bundle:

stella auth revoke verify \
  --bundle artifacts/revocation-bundle.json \
  --signature artifacts/revocation-bundle.json.jws \
  --key etc/authority/signing/authority-public.pem \
  --verbose

The verifier performs three checks:

  1. Prints the computed digest in sha256:<hex> format. Compare it with the exported .sha256 artefact.
  2. Parses the detached JWS header, confirms it advertises b64: false, captures the provider and kid hints, and reads the signing algorithm from the alg header (defaulting to ES256 when absent). The CLI verifies with the algorithm carried in the header; it does not have the Authority’s runtime configuration to compare against.
  3. Registers the supplied PEM key with the crypto provider registry and validates the signature (falling back to the managed provider when the hinted provider is unavailable).

A zero exit code means the bundle is ready for mirroring/import. Non-zero codes signal missing arguments, malformed JWS payloads, or signature mismatches; regenerate or re-sign the bundle before distribution.

Example

The repository contains an example bundle demonstrating a mixed export of token, subject, and client revocations. Use it as a reference for integration tests and tooling. Note that the subject entry is illustrative: it is valid against the schema, but no current Authority code path emits subject revocations (see Revocation entry categories).

Operations Quick Reference