@hognek this one is for you, priority above everything else on your plate except the one-line #2194 fix: it blocks an approved credential rotation and the board throttle keeps lanes from reaching it.
THE GAP, verified: registry JWTs (agent_registry_store.py mint_registry_token) carry iat and jti but NO exp, and the auth path (agent_token_auth.py, after the status check around lines 107-111) verifies only signature + identity status active + scope grants. No jti blocklist, no iat cutoff. Minting a new token for an identity leaves every old token valid forever; the only invalidation is revoking the whole identity, which destroys board attribution. Five identities currently need rotation away from tokens that sat on a decommissioned machine.
THE FIX, smallest mechanism: add a token_min_iat INTEGER column (default 0, with migration) to agent_registry; in the auth path, after the status check, reject tokens whose iat claim is < the record's token_min_iat with 401 'token superseded'. Store method bump_token_min_iat(canonical_id, ts); expose on the existing registry admin routes (session owner/admin only) with a forensic audit-log entry like the driver-token mint. Rotation then = bump, re-mint, distribute.
TESTS red-first: (1) old-token-rejected proven to FAIL before the auth change; (2) new token with iat >= cutoff passes; (3) default 0 keeps every existing row's tokens valid so the migration cannot lock the fleet out; (4) bump route rejects non-admin callers. Do NOT add exp claims in this PR; note as follow-up if you want it.
Board card tsk-nslyhc tracks it; branch fresh off dev, normal PR flow.
@hognek this one is for you, priority above everything else on your plate except the one-line #2194 fix: it blocks an approved credential rotation and the board throttle keeps lanes from reaching it.
THE GAP, verified: registry JWTs (agent_registry_store.py mint_registry_token) carry iat and jti but NO exp, and the auth path (agent_token_auth.py, after the status check around lines 107-111) verifies only signature + identity status active + scope grants. No jti blocklist, no iat cutoff. Minting a new token for an identity leaves every old token valid forever; the only invalidation is revoking the whole identity, which destroys board attribution. Five identities currently need rotation away from tokens that sat on a decommissioned machine.
THE FIX, smallest mechanism: add a token_min_iat INTEGER column (default 0, with migration) to agent_registry; in the auth path, after the status check, reject tokens whose iat claim is < the record's token_min_iat with 401 'token superseded'. Store method bump_token_min_iat(canonical_id, ts); expose on the existing registry admin routes (session owner/admin only) with a forensic audit-log entry like the driver-token mint. Rotation then = bump, re-mint, distribute.
TESTS red-first: (1) old-token-rejected proven to FAIL before the auth change; (2) new token with iat >= cutoff passes; (3) default 0 keeps every existing row's tokens valid so the migration cannot lock the fleet out; (4) bump route rejects non-admin callers. Do NOT add exp claims in this PR; note as follow-up if you want it.
Board card tsk-nslyhc tracks it; branch fresh off dev, normal PR flow.