Overview
All authenticated API routes in Brainstormer V2 follow a specific JWT pattern:- JWT Authentication Middleware extracts user info from Bearer token
- Middleware sets
request.userwith userId, organizationId, email - Route handlers access
request.user.organizationIdinstead of reading headers directly - The gateway verifies the JWT signature with
verifyJwt(token, JWT_SECRET); downstream services (4001–4006, not publicly exposed) trust gateway-forwarded headers and do not re-verify
What NOT to Do
Never Read Headers Directly
organization-id or user-id headers. These headers don’t exist in the request, so authentication will always fail with 401 errors.
Gateway Verifies, Downstream Services Trust Headers
verifyJwt(token, JWT_SECRET) (HMAC-SHA256). Only downstream services (ports 4001–4006) skip re-verification — they trust the auth context the gateway forwards as headers, and must never be exposed to the public internet.
Correct Pattern
Step 1: Add JWT Authentication Middleware
Step 2: Access User Info via request.user
Step 3: Skip Authentication for Public Routes
Why the Gateway Verifies and Downstream Services Trust Headers
Gateway Responsibility
Gateway Responsibility
API Gateway (Port 4000) is the only public ingress and verifies JWT signatures with
verifyJwt(token, JWT_SECRET) before routing to services.Trust Boundary
Trust Boundary
Services trust requests from the gateway because service ports (4001–4006) are not exposed to the public internet — only the gateway is.
Performance
Performance
Avoids repeated signature verification across services once the gateway has verified.
Simplicity
Simplicity
Downstream services only read the gateway-forwarded headers, not manage secrets.
Organization Selection
Common Errors and Solutions
Reference Implementation
Testing Checklist
- Added JWT authentication middleware with
fastify.addHook("preHandler", ...) - Defined
AuthenticatedRequestandJWTPayloadinterfaces - Using
request.user!.organizationIdinstead of reading headers - Public routes properly skip authentication
- Tested with valid JWT token (should succeed)
- Tested with missing Bearer token (should return 401)
- Tested with invalid JWT format (should return 401)
/services/bot/src/routes/bots.routes.ts
