Skip to content

Certify JWK rotation, stale-cache, and emergency revocation for edge capabilities #88

Open

Description

@ORESoftware

Goal

Turn key rotation for authenticated Cloudflare fallback and edge/origin proofs into an executable outage contract rather than an assumed operational property.

Coordinates:

This issue owns key lifecycle and outage semantics, not the capability grant model itself.

Rotation model

Define a bounded key lifecycle with explicit states such as introduced/active/retiring/revoked and prove:

  • new signing key can be published before first use;
  • old + new verification keys overlap for a bounded interval;
  • issuers stop minting with the retiring key before verifiers remove it;
  • unknown kid fails closed and does not trigger unbounded refetch loops;
  • stale verifier caches have a maximum accepted age;
  • cache refresh respects HTTP/JWK freshness metadata within a repository-owned upper bound;
  • a normal issuer/JWK endpoint outage does not cause indefinite trust of stale keys;
  • emergency revocation has a documented faster path than ordinary TTL expiry.

Separation of key sets

If authenticated fallback capabilities and edge→origin service proofs use distinct issuers/audiences or key sets, keep them cryptographically and operationally distinct. Do not create one universal high-authority key merely for convenience.

Failure semantics

Exercise at least:

  1. old key only;
  2. old + new overlap;
  3. issuer signs with new key after verifiers have learned it;
  4. verifier has stale old-only cache when new token arrives;
  5. JWK endpoint unavailable while cached keys are still inside freshness bound;
  6. JWK endpoint unavailable after maximum stale bound;
  7. unknown kid flood;
  8. malformed JWK / duplicate kid / unsupported algorithm;
  9. key removed too early;
  10. emergency revocation of a compromised active key;
  11. clock skew near nbf / exp;
  12. rollback to an older JWK document/version.

Cache / anti-amplification requirements

  • one unknown kid must not cause every request/isolate to create unbounded JWK traffic;
  • use bounded negative/single-flight refresh semantics where practical;
  • key cache cardinality and document size are bounded;
  • refresh failures are typed/redacted;
  • no JWT/capability body, provider secret, or signing private key enters logs/artifacts.

Evidence

Add deterministic fake-clock unit tests plus Worker-runtime integration coverage. Retain a compact rotation timeline/receipt proving which key ids were accepted/rejected at each phase without retaining bearer tokens.

Done when

The edge can survive routine overlapping rotation, fails closed after bounded stale-key tolerance, can reject a compromised key promptly, and every transition is covered without depending on Shared Auth or the primary Zed API being continuously reachable during verification.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions