Skip to content

feat: API key rotation and revocation (#40) - #142

Merged
victorisiguzoruzoma874 merged 1 commit into
SynapsVault:mainfrom
wendyamoni-creator:feat/api-key-rotation-40
Oct 19, 2026
Merged

victorisiguzoruzoma874 merged 1 commit into
SynapsVault:mainfrom
wendyamoni-creator:feat/api-key-rotation-40

Conversation

@wendyamoni-creator

@wendyamoni-creator wendyamoni-creator commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #40.

Publishers can now rotate their API key via POST /publishers/me/api-keys/rotate. The old key is invalidated immediately; the new plaintext key is returned once in the response.

Changes

File Change
drizzle/0012_api_key_rotation.sql New migration — adds api_key_revoked_at column to publishers
src/db/schema.ts apiKeyRevokedAt nullable timestamp field
src/middleware/apiKeyAuth.ts Rejects keys where apiKeyRevokedAt IS NOT NULL
src/services/publisherService.ts rotateApiKey() — single atomic UPDATE that swaps the hash
src/routes/publishers.ts POST /publishers/me/api-keys/rotate route
src/routes/publishers.api-key-rotation.test.ts 9 new tests (new file)
src/routes/publishers.test.ts Fix authedPublisher fixture — add apiKeyRevokedAt: null

How it works

  • Rotation: rotateApiKey() does one atomic UPDATE — sets apiKeyHash to the new hash and sets apiKeyRevokedAt = null. The old key's hash is overwritten so it matches nothing on the next lookup.
  • Explicit revocation (e.g. admin): set apiKeyRevokedAt to a timestamp without changing the hash. apiKeyAuth rejects any key whose row has a non-null apiKeyRevokedAt, even if the hash still matches.

Acceptance criteria

  • The old key returns 401 after rotation
  • The new key works (200)
  • Tests cover both cases

Tested

Test Files  2 passed (2)
     Tests  25 passed (25)
```  closes #40 

Add POST /publishers/me/api-keys/rotate that issues a new key and
immediately invalidates the old one.

Changes:
- drizzle/0012_api_key_rotation.sql: add api_key_revoked_at column
- src/db/schema.ts: add apiKeyRevokedAt nullable timestamp field
- src/middleware/apiKeyAuth.ts: reject keys where apiKeyRevokedAt IS NOT NULL
- src/services/publisherService.ts: rotateApiKey() — atomic hash swap
- src/routes/publishers.ts: POST /publishers/me/api-keys/rotate route
- src/routes/publishers.api-key-rotation.test.ts: 9 new tests
- src/routes/publishers.test.ts: fix authedPublisher fixture (add apiKeyRevokedAt: null)

Acceptance criteria met:
- Old key returns 401 after rotation (hash replaced in DB)
- New key works immediately (200)
- Tests cover both cases plus explicit revocation via apiKeyRevokedAt
@drips-wave

drips-wave Bot commented Oct 19, 2026

Copy link
Copy Markdown

@wendyamoni-creator Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@vercel

vercel Bot commented Oct 19, 2026

Copy link
Copy Markdown

@wendyamoni-creator is attempting to deploy a commit to the work Team on Vercel.

A member of the Team first needs to authorize it.

@victorisiguzoruzoma874
victorisiguzoruzoma874 merged commit 366828d into SynapsVault:main Oct 19, 2026
0 of 2 checks passed
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.

Add API-key rotation and revocation

2 participants