Skip to content

ADR 0026 §3: Audit-log-derived JTI backfill for emergency key rotation #1214

Description

@gtema

ADR 0026 §3 ("Emergency Rotation and Signing Key Compromise") describes the
JTI revocation list populated at emergency-rotation time:

The list initially includes the jti of any tokens issued within the
compromise window (derived from the audit log).

This is not built. confirm-rotate-signing-key (#1017/#1020) takes
revoke_jtis: Vec<String> as an operator-supplied, repeatable
--revoke-jti CLI flag
(crates/cli-manage/src/oauth2/confirm_rotate_signing_key.rs) — the operator
must already know which JTIs to revoke and paste them in by hand. Nothing
automatically finds "every token minted for this domain between timestamp A
and B" the way the ADR describes.

This was explicitly scoped out of the July 2026 post-Phase-6 follow-up pass
(alongside #1213, the UDS/loopback emergency-rotation fallback) because it
depends on a capability that doesn't exist yet anywhere in the codebase: a
queryable audit-log store. CADF audit events (ADR 0023) are currently
emitted as best-effort dispatch/logging only — there's no persistence layer
that can answer "list all jtis issued for domain X between A and B".

What building this actually requires

  1. A queryable audit-log persistence layer (general-purpose, useful well
    beyond this one use case — CADF events currently aren't stored anywhere
    queryable at all).
  2. On top of that, a query keyed on domain_id + time range + event type,
    filtered to token-issuance events, extracting jti.
  3. Wiring confirm-rotate-signing-key (or a new emergency-rotation variant)
    to accept a compromise-window time range and auto-populate
    revoke_jtis from that query, in addition to (not necessarily
    replacing) the current manual --revoke-jti path.

Recommend scoping the audit-log queryability piece as its own ADR/design
effort first, since it's the real dependency here — this issue's actual
JTI-backfill logic is comparatively thin once that exists.

Sub-issue of #939.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions