Security & Authentication Constraints¶
This spec documents the guardrails for the authentication and RBAC feature slice so that every surface integrates consistently. The goal is to give future feature specs a concise reference for how to issue tokens, secure cookies, and enforce role-based access across Kong, OPA, and the backend services.
1. Authentication Flow¶
- Primary trust path: Ory Kratos manages user sessions through its
ory_kratos_sessioncookie.backend/src/middleware/kratos-auth.ts(thekratosAuthenticatemiddleware) validates Kratos sessions on every API call before falling back to the gateway headers or raw JWT. - Secondary path (Kong headers): When Kong handles JWT verification, it injects
X-User-Id,X-User-Role, andX-User-Emailheaders.backend/src/middleware/auth.tsloads those headers, fetches the user name from Prisma, and populatesreq.userso downstream handlers never have to re-parse the token. - Tertiary path (direct JWT): Local development or special clients may call
extractTokenFromHeader/verifyTokenfrombackend/src/lib/jwt.ts. The middleware honorsAuthorization: Bearer, anauth_tokencookie, or Kratos JWTs, but will always reject if theexpclaim is missing or expired. - Fail-safe: If no valid credential is found, the request terminates with
401 Authentication required.
2. JWT Token Policy¶
- Issuance: Tokens are issued via
POST /api/auth/tokenand/api/auth/token/refresh(seebackend/src/routes/token.ts). They are generated bygenerateKongJWT(backend/src/lib/jwt-kong.ts) and populateiss = "studio-idp",aud = "studio-api", and the user metadata (sub,email,role,name). - Lifetime: Every token is valid for exactly 24 hours (
exp = issued_at + 86 400). Kong’sjwtplugin onapi-protected,ai-brain-route,agent-route-segregated, anddocument-rag-routeverifies only theexpclaim, so the backend MUST never issue tokens without that claim. - Environment dependency: The shared
JWT_SECRETenvironment variable is mandatory in all environments; the helpers throw when it is missing (backend/src/lib/jwt.ts,backend/src/lib/jwt-kong.ts). Always provision per-service secrets (the Kong consumer ingateway/kong.ymlis bound tostudio-idp). - Response contract: Token endpoints return
{ token_type: 'Bearer', expires_in: 86400, token, user: { id, email, role, name } }. This payload should be consumed by clients to refresh tokens before expiration.
3. Cookie & Session Constraints¶
- HttpOnly cookies: Any cookies issued by the platform (
ory_kratos_session,auth_token, session refresh cookies, etc.) MUST setHttpOnly,Secure, andSameSite=Strictto minimize XSS exposure. The backend expects anauth_tokencookie when direct JWT fallback is triggered, so the client must mirror the cookie name exactly. - Kratos session handshake: When
kratosAuthenticatecallskratos.toSession, it will drop authentication ifx-session-tokenis present but invalid (i.e., a JWT). Token issuance should never embed Kratos session state insidex-session-token. - Cookie lifetime: The Kratos session cookie lifespan should align with the 24-hour token window; the spec forbids creating server cookies with longer TTL than our JWTs unless explicitly refreshed through
/api/auth/token/refresh.
4. RBAC Enforcement¶
- Default deny: The OPA policy (
gateway/opa/policies/rbac.rego) starts fromdefault allow := false. Every protected route must have an explicitallowrule. - Gateway role map: For each prefix, the policy enumerates allowed roles:
/api/projects:["manager", "auditor", "customer", "compliance"]/api/admin:["admin"]/api/manager:["admin", "manager"]/api/auditor:["admin", "auditor"](with read-only access for managers)/api/customer:["admin", "customer"](GET allowed for managers)/api/chat,/api/agent,/agent-api,/api/evidence,/api/uploads,/api/secure-view:["admin", "manager", "auditor", "customer"]/api/ai:["admin", "manager", "auditor", "customer", "compliance"]/api/rag:["customer", "auditor"]/api/compliance:["admin", "manager", "auditor", "customer", "compliance"]/api/learning:["admin", "manager", "auditor", "customer", "employee"]/api/casb,/api/findings:["customer", "auditor"]/api/agents:["customer", "auditor", "admin", "manager"]/api/users:["admin", "manager", "customer"]- Every other
/apiroute is denied unless a newallowrule is added (e.g.,/api/systemand options requests are explicitly permitted). - Backend reinforcement: On top of Kong, the backend invokes
checkAuthorization(backend/src/lib/opa.ts) through theauthorizeWithOPAmiddleware. For critical endpoints,requireRolestill exists as a secondary check. - Role consistency: Backend Prisma models limit
roleto'admin' | 'auditor' | 'customer' | 'manager' | 'reviewer'. Feature specs must ensure any new role introduced in OPA has a backing DB value and Kratos trait; otherwise, it cannot appear in JWT payloads.
5. Gateway + Infrastructure Constraints¶
- Gateway plugins: Kong runs CORS, rate limiting, request-size limiting, JWT verification, and OPA on the protected API routes (
gateway/kong.yml). Feature specs must declare whether an endpoint belongs toapi-protectedor another route because that determines which plugins run. - CORS list: Allowed origins are explicitly enumerated (
localhost,demo.cybergaar.com, etc.); do not add*or wide wildcards. Any new frontend host must be appended to this list and kept in sync with the docs. - OPA availability: The backend fails closed if OPA is unreachable (
checkAuthorizationreturnsfalse). Systems must keep the OPA service healthy; the gateway routes rely onallow_on_error: false.
6. Guiding Constraints for New Features¶
- Authenticate every new API route via
authenticate, guard critical endpoints withauthorizeWithOPA, and only add customrequireRolechecks when logic demands a narrower role (ailments like server health or admin-only metrics). - When introducing new roles or resources, document the allowed paths in
gateway/opa/policies/rbac.rego, update Kratos traits (and resulting JWT claims), and re-run sync scripts or seeders so the Prismarolefield stays accurate. - Token refreshes should always occur through
/api/auth/token/refreshrather than reissuing cookies manually; the/tokenhandler already issues a fresh 24-hour token and updatesexpires_in. - Any client consuming tokens must store them in memory or
LocalStoragefor APIs but must rely on the HttpOnly cookie for automatic session management—never mirror tokens into 3rd-party script-accessible storage.
References¶
backend/src/middleware/auth.tsbackend/src/middleware/kratos-auth.tsbackend/src/lib/jwt.ts&backend/src/lib/jwt-kong.tsbackend/src/routes/token.tsbackend/src/lib/opa.tsgateway/opa/policies/rbac.regogateway/kong.yml