fix: health readiness/liveness split, service-auth key rotation, transport-aware CSRF Secure flag, and reqId in error bodies (#562, #555, #560, #558) - #641
Merged
therealjhay merged 10 commits intoSep 2, 2026
Conversation
Add a dedicated liveness probe at /api/health/live that always returns 200 when the gateway process is up. Keep /api/health as the readiness probe that returns 503 when critical dependents (DB, upstream engines) are down, so load balancers stop routing traffic to a degraded gateway.
Test that GET /api/health/live always returns 200 even when all downstream services are down. Test that GET /api/health returns 503 when critical dependents fail.
…ation, CSRF cookie Secure, reqId in errors - createServiceAuth/registerServiceAuth: accept string | string[] to support multiple valid keys during rotation windows. Both old and new keys work during overlap; remove old key once all consumers migrate. - buildCsrfCookieHeader: set Secure based on actual request protocol (https) instead of NODE_ENV, fixing staging HTTPS environments. - registerErrorHandler: include reqId (x-request-id) in all error response bodies so support can correlate client complaints with logs.
…RF cookie, reqId tests - Test overlapping key rotation (two valid keys, invalid rejected). - Test buildCsrfCookieHeader: HTTPS gets Secure, HTTP does not, x-forwarded-proto is respected. - Verify reqId present in Zod 400, Fastify error, and generic 500 error response bodies.
Allow callers of buildApp to override the inter-service secret with a string or string[] for testing key rotation scenarios.
Test that overlapping keys work during rotation window. Test that createServiceAuth accepts arrays and rejects empty arrays.
Extend the ErrorResponse type and createErrorResponse function in errors.ts to support an optional reqId field, matching the main index.ts changes.
Extend the ErrorResponse type and createErrorResponse function in shared/validation/index.ts to support an optional reqId parameter, enabling error response bodies to carry the request id for support correlation.
Assert that a Zod validation error on gateway routes includes reqId in the response body for support correlation.
…Response Add test that reads plugins.ts source to confirm the error handler passes the request id to createErrorResponse for body correlation.
|
@TheCodingChef-eth 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! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR resolves four api-gateway issues in a single branch, with each file committed independently.
closes #562 — Health endpoint readiness vs liveness split
Problem: /api/health returned 503 for unhealthy status, but there was no dedicated liveness probe. Load balancers need a simple liveness check (always 200 when the process is up) separate from the readiness check.
Solution:
Readiness 503 demo:
GET /api/health → 503 { status: "unhealthy", service: "api-gateway", ... }
GET /api/health/live → 200 { status: "alive", service: "api-gateway" }
closes api-gateway service-auth plugin doesn't rotate internal service keys #555 — Service-auth key rotation
Problem: Internal service credentials were static with no rotation mechanism. Compromise required full redeploy.
Solution:
Rotation demo:
// Deploy with both keys during rotation window
registerServiceAuth(fastify, [OLD_SECRET, NEW_SECRET]);
// After all consumers switch, deploy with only the new key
registerServiceAuth(fastify, NEW_SECRET);
closes #560 — CSRF cookie Secure flag transport-aware
Problem: buildCsrfCookieHeader set Secure only when NODE_ENV === 'production'. Staging HTTPS environments in NODE_ENV=development served cookies without Secure.
Solution:
Transport-aware demo:
// HTTPS request → Secure flag set
buildCsrfCookieHeader('csrf', 'token', { protocol: 'https' })
// → "csrf=token; Path=/; SameSite=Strict; HttpOnly; Secure"
// HTTP request → no Secure flag
buildCsrfCookieHeader('csrf', 'token', { protocol: 'http' })
// → "csrf=token; Path=/; SameSite=Strict; HttpOnly"
closes #558 — reqId in error response bodies
Problem: Error responses didn't include the request id, so support couldn't correlate client complaints with server logs.
Solution:
Error body with reqId:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"reqId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Files changed
File Issue Description
services/api-gateway/src/health.ts api-gateway health endpoint responds 200 even when some dependents fail #562 Add /api/health/live liveness endpoint
services/api-gateway/src/health-all.test.ts api-gateway health endpoint responds 200 even when some dependents fail #562 Tests for liveness 200 and readiness 503
shared/validation/plugins.ts api-gateway service-auth plugin doesn't rotate internal service keys #555,api-gateway CSRF cookie lacks Secure flag in non-prod HTTPS #560,api-gateway genReqId is generated but not used in error responses #558 Key rotation, CSRF Secure, reqId in error handler
shared/validation/plugins.test.ts api-gateway service-auth plugin doesn't rotate internal service keys #555,api-gateway CSRF cookie lacks Secure flag in non-prod HTTPS #560,api-gateway genReqId is generated but not used in error responses #558 Tests for all three features
services/api-gateway/src/index.ts api-gateway service-auth plugin doesn't rotate internal service keys #555 Add interServiceSecret to AppOptions
services/api-gateway/src/service-auth.test.ts api-gateway service-auth plugin doesn't rotate internal service keys #555 Key rotation tests on gateway
shared/validation/index.ts api-gateway genReqId is generated but not used in error responses #558 Add reqId to ErrorResponse
shared/validation/errors.ts api-gateway genReqId is generated but not used in error responses #558 Add reqId to ErrorResponse
services/api-gateway/src/error-response.test.ts api-gateway genReqId is generated but not used in error responses #558 Verify reqId in gateway errors
services/api-gateway/src/genReqId-usage.test.ts api-gateway genReqId is generated but not used in error responses #558 Verify error handler passes reqId