Skip to content

fix: rotate database credentials from Vault without restart - #773

Merged
nonsobethel0-dev merged 2 commits into
Parashield-Protocol:mainfrom
wandooadzer-cmyk:fix/db-credential-rotation
Oct 18, 2026
Merged

nonsobethel0-dev merged 2 commits into
Parashield-Protocol:mainfrom
wandooadzer-cmyk:fix/db-credential-rotation

Conversation

@wandooadzer-cmyk

Copy link
Copy Markdown
Contributor

Database credentials were loaded from Vault once at startup and baked into the PrismaClient, so rotating them in Vault left the app on stale (and eventually revoked) credentials until a restart.

  • PrismaService now wraps a swappable PrismaClient (interface merge + Proxy keep the existing API for all callers) and exposes rotateCredentials(): new clients are connected before being swapped in, a rejected credential keeps the current connection, and replaced clients are drained for DATABASE_ROTATION_DRAIN_MS (default 30s) before disconnecting.
  • New DatabaseCredentialRotationService polls Vault every VAULT_REFRESH_INTERVAL_MS (default 5m, 0 disables) and applies changes to DATABASE_URL / DATABASE_REPLICA_URL; Vault or connect failures are logged and retried on the next tick.
  • Split fetchVaultSecrets() out of loadVaultSecrets() for runtime reuse.
  • Validate the new env vars, document rotation in the README, and add tests covering rotation, failure fallback, draining, and polling.

About this PR

This PR resolves 4 enhancement issues:

Changes

#375 - API versioning strategy

  • Implemented API versioning interceptor that adds X-API-Version response header
  • Added Deprecation header for v1 with Link header pointing to v2 successor
  • Updated Swagger config to support x-api-version header for API version negotiation

#373 - Pagination on policy and claims list endpoints

  • Added page and limit query parameters to GET /api/v1/products endpoint
  • Updated getActiveProducts service method to support Prisma-based pagination with take/skip
  • Claims list endpoints (getClaimsByWalletQuery, getClaimHistory) already had pagination

#372 - Rate limiting on claim submission endpoint

  • Added claim-specific rate limiting (limit: 5/60s) to POST /api/v1/claims endpoint
  • Uses @Throttle decorator with stricter limits than global throttler (60/60s)

#374 - Webhook support for policy/claim status changes

  • Created WebhooksService with register/unregister/list and status notification methods
  • Created WebhooksController with POST /api/v1/webhooks/register and GET /api/v1/webhooks endpoints
  • Policy status changes (e.g., cancel) trigger webhooks with policy.status.change event
  • Claim status changes (e.g., PROCESSING → FAILED, PROCESSING → CLAIMED) trigger webhooks with claim.status.change event

Issue Closure

This PR closes the following issues using GitHub keyword syntax:

Verification

Closes #658
Closes #657
Closes #656
Closes #655

  • All endpoints return proper pagination metadata ({ success, data, total, page, limit })
  • Rate limiting prevents claim submission spam beyond 5 attempts per 60 seconds
  • Webhooks can be registered with specific events (policy.status.change, claim.status.change)
  • API versioning headers are present on all responses

Database credentials were loaded from Vault once at startup and baked into
the PrismaClient, so rotating them in Vault left the app on stale (and
eventually revoked) credentials until a restart.

- PrismaService now wraps a swappable PrismaClient (interface merge + Proxy
  keep the existing API for all callers) and exposes rotateCredentials():
  new clients are connected before being swapped in, a rejected credential
  keeps the current connection, and replaced clients are drained for
  DATABASE_ROTATION_DRAIN_MS (default 30s) before disconnecting.
- New DatabaseCredentialRotationService polls Vault every
  VAULT_REFRESH_INTERVAL_MS (default 5m, 0 disables) and applies changes to
  DATABASE_URL / DATABASE_REPLICA_URL; Vault or connect failures are logged
  and retried on the next tick.
- Split fetchVaultSecrets() out of loadVaultSecrets() for runtime reuse.
- Validate the new env vars, document rotation in the README, and add tests
  covering rotation, failure fallback, draining, and polling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@drips-wave

drips-wave Bot commented Oct 18, 2026

Copy link
Copy Markdown

@wandooadzer-cmyk 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

@nonsobethel0-dev
nonsobethel0-dev merged commit 18b86c1 into Parashield-Protocol:main Oct 18, 2026
0 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment