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

71 lines
4.0 KiB
Markdown

# 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.