Revocation Design¶
How Auths handles attestation revocation: threat model, data model, verification, and future directions.
Current Model¶
Signed revoked_at Field¶
Revocation status is embedded directly in the attestation's signed canonical body as:
Because revoked_at is included in the canonical JSON that both the identity key and device key sign over, any post-hoc tampering (stripping, injecting, or changing the timestamp) invalidates both signatures. This is the core tamper-resistance guarantee.
Revocation Flow¶
- The identity holder calls
create_signed_revocation()(auths-id/src/attestation/revoke.rs). - A
CanonicalRevocationDatastruct is built containing therevoked_attimestamp and signed by the identity key only (the device does not counter-sign revocations). - The resulting
Attestationobject hasrevoked_at: Some(timestamp)and an emptydevice_signature. - The revocation attestation is stored as a Git commit in the
refs/auths/ref hierarchy, preserving full history.
Verification¶
Verification (auths-verifier/src/verify.rs) checks revocation at two levels:
verify_with_keys_at()(time-aware): Ifrevoked_at <= reference_time, the attestation is rejected with"Attestation revoked". This supports both current-time and historical-time verification.verify_single_attestation()(chain walk): Callsatt.is_revoked()(which checksrevoked_at.is_some()) before verifying signatures. A revoked intermediate link halts the chain withVerificationStatus::Revoked.
Git Storage¶
Revocation attestations are stored alongside normal attestations in:
The commit history of this ref records the full attestation lifecycle: creation, any updates, and revocation. Git's immutable commit DAG provides an audit trail.
Security Properties¶
| Property | Guarantee |
|---|---|
| Tamper-proof revocation | revoked_at is inside the signed envelope; any modification breaks Ed25519 signatures |
| Non-repudiation | The identity key signs the revocation; only the key holder can revoke |
| Audit trail | Git commit history records when revocation was stored |
| Time-aware verification | verify_at_time() evaluates revocation relative to a caller-supplied timestamp |
Enterprise Considerations¶
For deployments that need real-time revocation checking without cloning Git repos:
Registry-Based Revocation Endpoint¶
A future extension could expose an HTTP endpoint that serves revocation status:
This would be backed by the same Git storage but indexed for O(1) lookup (similar to auths-index). The signed attestation itself remains the source of truth; the endpoint is a read-through cache.
CRL/OCSP Analogy¶
The current model is analogous to "stapled" revocation (like OCSP stapling in TLS): the revocation proof travels with the attestation. A registry endpoint would add a "pull" model for clients that cannot access the Git repository directly.
Limitations¶
- Offline revocation propagation: Revocation only takes effect when the consuming party fetches the updated attestation from Git. There is no push notification mechanism.
- Single-signer revocation: Only the identity key can revoke. There is no multi-party revocation ceremony (though this could be built on top of the
ThresholdPolicyinfrastructure). - No un-revocation: Once
revoked_atis set and signed, a new attestation must be issued rather than "un-revoking" the old one.