Files
git.stella-ops.org/docs/security/revocation-bundle.md
master 607e72e2a1
Some checks failed
Build Test Deploy / docs (push) Has been cancelled
Build Test Deploy / deploy (push) Has been cancelled
Build Test Deploy / build-test (push) Has been cancelled
Build Test Deploy / authority-container (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
up
2025-10-12 20:37:18 +03:00

4.0 KiB

Authority Revocation Bundle

The Authority service exports revocation information as an offline-friendly JSON document plus a detached JWS signature. Operators can mirror the bundle alongside Feedser exports to ensure air-gapped scanners receive the latest token, subject, and client revocations.

File layout

Artefact Description
revocation-bundle.json Canonical JSON document describing revoked entities. Validates against etc/authority/revocation_bundle.schema.json.
revocation-bundle.json.jws Detached JWS signature covering the exact UTF-8 bytes of revocation-bundle.json.
revocation-bundle.json.sha256 Hex-encoded SHA-256 digest used by mirror automation (optional but recommended).

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

Deterministic formatting rules

  • JSON is serialised with UTF-8 encoding, 2-space indentation, and lexicographically sorted object keys.
  • Arrays are sorted by deterministic keys:
    • Top-level revocations sorted by (category, id, revokedAt).
    • Nested arrays (scopes) sorted ascending, unique enforced.
  • Numeric values (sequence) are emitted without leading zeros.
  • Timestamps use UTC ISO-8601 format with Z suffix.

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

Category Description Required fields
token A single OAuth token (access, refresh, device, authorization code). tokenType, clientId, revokedAt, optional subjectId
subject All credentials issued to a subject (user/service account). subjectId, revokedAt
client Entire OAuth client registration is revoked. clientId, revokedAt
key Signing/encryption key material revoked. id, revokedAt

reason is a machine-friendly code (compromised, rotation, policy, lifecycle, etc). reasonDescription may include a short operator note.

Detached JWS workflow

  1. Serialise revocation-bundle.json using the deterministic rules.
  2. Compute SHA-256 digest; write to revocation-bundle.json.sha256.
  3. Sign using ES256 (default) with the configured Authority signing key. The JWS header uses:
    {
      "alg": "ES256",
      "kid": "{signingKeyId}",
      "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 JWKS (/.well-known/jwks.json) or the offline key bundle.
  4. Verify the detached JWS using the stored signing key (example tooling coming with stella auth revoke verify).

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.

Operations Quick Reference

  • stella auth revoke export emits a canonical JSON bundle, .sha256 digest, and detached JWS signature in one command. Use --output to write into your mirror staging directory.
  • stella auth revoke verify validates a bundle using cached JWKS or an offline PEM key and reports digest mismatches before distribution.
  • POST /internal/revocations/export provides the same payload for orchestrators that already talk to the bootstrap API.
  • POST /internal/signing/rotate rotates JWKS material without downtime; always export a fresh bundle afterward so downstream mirrors receive signatures from the new kid.
  • Offline Kit automation should mirror revocation-bundle.json* alongside Feedser exports so agents ingest revocations during the same sync pass.