Skip to content

Revocation availability: signed heartbeat to decouple freshness from full list fetch #2325

@bokelley

Description

@bokelley

Follow-up to PR #2323 expert review (security-reviewer).

The revocation stale fail-closed rule (governance and transport profiles) creates a single-endpoint DoS surface: an attacker who DoSes a brand.json origin's /.well-known/*-revocations.json can halt all signed spend-committing traffic for that origin until the operator notices.

Current mitigation is grace ≈ 2× polling interval. Not enough — revocation endpoint outage of a few minutes will break production in the 4.0 flip world.

Proposal: decouple freshness from full-list availability via a signed heartbeat.

  • Separate lightweight endpoint (e.g., /.well-known/governance-revocations-heartbeat.json and /.well-known/request-signing-revocations-heartbeat.json, or one combined endpoint).
  • Returns a small signed object: { issuer, list_hash, heartbeat_at, next_heartbeat }.
  • If the heartbeat is fresh AND list_hash matches the verifier's cached full-list hash, verifiers MAY continue to trust the cached list past the full list's next_update.
  • The heartbeat is small enough to serve from a CDN edge without the signing infrastructure needing to be available.
  • The DoS attacker now has to take down BOTH endpoints to halt traffic.

Also proposed: tier grace by severity.

  • Extend grace for revoked_jtis (per-token revocation) to e.g. 4× polling interval. jti revocations are governance-only and already bounded by exp.
  • Keep tight grace for revoked_kids (whole-key compromise). This is the attack worth failing-closed for.

Scope: spec update to both the JWS profile (#revocation section) and the RFC 9421 profile (#transport-revocation section). Schema addition for the heartbeat object's signed shape.

Priority: the longer we operate with pure fail-closed, the more production traffic we block on revocation-endpoint blips. Should land well before 4.0 required signing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.rfcProtocol change — auto-adds to roadmap board

    Type

    No type

    Projects

    Status

    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions