Skip to content

fix(auth): refuse a stored credential epoch below 1 so claimless bearers never match #1031

Closed

Description

@mforce

Gap

#364 retires credential epoch 0 permanently, and AGENTS.md says "a missing or malformed claim is always a mismatch". That holds only while every stored CredentialEpoch is at least 1. Nothing enforces it: the column defaults to 1, and there is no check constraint, no domain guard and no refusal in the verifier.

Codex Astra proved the dependency with a throwaway real-Postgres probe during the #857 design review (2026-10-03, /home/mforce/.cluckwork-slices/reviews/857-design-astra.md). It set a user's stored epoch to 0 with SQL, then sent correctly signed Owner bearers with no epoch claim, a malformed claim, and an explicit "0". All three got 200 from /api/v1/users.

No code path writes 0 today, so this is not a live hole. It is a fail-closed guarantee that rests on data instead of structure. A bad backfill, manual SQL, or a future code path that writes 0 would silently re-enable claimless and malformed bearers for that user.

What closing it needs

Done when

This is a behaviour change, so it is deliberately not part of the #857 extraction.

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

    bugSomething isn't workingseverity:p3Defect: degraded or partial behaviour

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions