# 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`](../../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: ```json { "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](revocation-bundle-example.json) 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.