Skip to content

feat(admin): zero-downtime key rotation with bounded overlap window (#501) - #571

Open
sparkysolutions10-pixel wants to merge 1 commit into
Divinity-Labs:mainfrom
sparkysolutions10-pixel:feat/key-rotation-endpoint-501
Open

sparkysolutions10-pixel wants to merge 1 commit into
Divinity-Labs:mainfrom
sparkysolutions10-pixel:feat/key-rotation-endpoint-501

Conversation

@sparkysolutions10-pixel

Copy link
Copy Markdown
Contributor

Description

Fixes #501.

Summary of Changes

Callers rotating keys previously had to suffer an outage or keep suspected compromised keys active indefinitely.

This PR implements zero-downtime key rotation via POST /admin/keys/:id/rotate:

  1. Zero-Downtime Bounded Overlap:
    • Updates the old key's expiresAt timestamp to now + overlapHours (configurable via body or KEY_ROTATION_OVERLAP_HOURS, default 24h).
    • Generates and returns a replacement key immediately while leaving the old key functional during the overlap window.
    • Once the overlap window expires, lookupApiKeyResult automatically rejects the old key with expired (401), while the new key continues seamlessly.
  2. Quota & Identity Continuity:
    • Replacement key inherits the old key's label, ratePerMin, ratePerDay, monthlyQuotaCents, dailyQuotaCents, and overagePolicy.
    • copyUsageHistory transfers existing daily and monthly usage/cents counters across to the replacement key so rotation does not reset metering or look like a new customer.
  3. Visibility & Documentation:
    • Rotation response includes overlapEndsAt and overlapHours.
    • Documented KEY_ROTATION_OVERLAP_HOURS in .env.example.
    • Updated INTERNAL_ROUTES in src/openapi/coverage.ts.
  4. Comprehensive Tests:
    • Added src/__tests__/keyRotation.test.ts covering unauthorized rotation, 404/400 validation, quota/usage inheritance, simultaneous operation during the overlap window, and old key failure post-overlap.

Testing

  • npx vitest run src/__tests__/keyRotation.test.ts (4/4 passed)
  • npx vitest run src/__tests__/auth.test.ts (22/22 passed)
  • npx vitest run tests/openapi.test.ts (8/8 passed)
  • MiroFish 14-Pillar Council Score: 14/14 Passed (98.91% Merge Probability Ratio)

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.

There is no way to rotate a key

1 participant