Skip to content

Wire API-key renewal, add revocation + selectable expiry (closes #3)#4

Open
Rashmi-278 wants to merge 1 commit into
mainfrom
fix/api-key-renewal-revoke-expiry
Open

Wire API-key renewal, add revocation + selectable expiry (closes #3)#4
Rashmi-278 wants to merge 1 commit into
mainfrom
fix/api-key-renewal-revoke-expiry

Conversation

@Rashmi-278

Copy link
Copy Markdown
Member

Fixes #3.

Registered users could not generate a replacement API key from the UI. The "Generate API Key" button only called POST /api/auth/register, which returns 409 Already registered for existing accounts, while the working POST /api/auth/keys endpoint had no UI control. Reported by @aolieman, who had to hand-craft a Privy-token request to mint a key.

Changes

Renewal (fixes the reported lockout)

  • New "Generate new API key" button on /get-api-access, shown once registered, calling POST /api/auth/keys with the Privy Bearer token.
  • Returned raw key surfaces in the existing save-it-now panel; /api/auth/keys query invalidated.

Selectable expiry

  • Optional durationDays on the mint routes, validated against an allow-list (90 / 180 / 365); anything else → 400.
  • Default bumped from 3 months to 1 year. Duration selector added to the UI; hard-coded "expire after 3 months" copy updated.

Revocation

  • New DELETE /api/auth/keys/:id behind verifyPrivyToken, calling storage.revokeApiKey().
  • Ownership check: only the caller's own keys are considered — a key owned by anyone else is indistinguishable from a non-existent one (404) and can never be revoked cross-account.
  • Per-key Revoke button with a confirm dialog.

Cap

  • Active-key limit raised from 3 to 5; a 6th returns a clear 400.

Notes / blast radius

Auth + keys — security-sensitive. The two review-critical items are the ownership check on revoke and the expiry allow-list. No schema migration (api_keys.expires_at / status already exist). Backward compatible: existing 3-month keys and the first-time register path are untouched.

Testing

  • resolveKeyExpiry allow-list logic unit-tested in isolation.
  • Changed files typecheck clean (pre-existing repo typecheck errors are in unrelated files).
  • Not exercised end-to-end: requires the Neon DB + Privy secrets, which aren't available in this environment. A human should run the live renew/revoke/expiry flow against a real Privy login before merge.

Diagnosis and spec: docs/maintenance-flow/issue-3-manual-triage.md.

https://claude.ai/code/session_01BxtA4nBczx1CaSDcBfZ24W

)

Registered users were locked out of self-service key renewal: the UI only
called POST /api/auth/register, which 409s for existing accounts, while the
working POST /api/auth/keys endpoint had no UI control. Reported by @aolieman
(#3), who had to hand-craft a Privy-token request to mint a key.

- Wire "Generate new API key" button to POST /api/auth/keys for registered users
- Add selectable key lifetime (3mo / 6mo / 1yr) with server-side allow-list;
  default bumped from 3 months to 1 year
- Add DELETE /api/auth/keys/:id with an ownership check (a token can only
  revoke its own keys; others' keys return 404) + per-key Revoke button
- Raise active-key cap from 3 to 5

No schema migration; existing keys and the register flow are unaffected.
Auth/keys is security-sensitive — ownership check and duration allow-list
need human review.

Docs: adds the maintenance-flow design + the manual triage of #3 that
produced this fix.

Claude-Session: https://claude.ai/code/session_01BxtA4nBczx1CaSDcBfZ24W
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Renew/revoke API key flow

1 participant