Skip to content

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_session cookie. backend/src/middleware/kratos-auth.ts (the kratosAuthenticate middleware) 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, and X-User-Email headers. backend/src/middleware/auth.ts loads those headers, fetches the user name from Prisma, and populates req.user so downstream handlers never have to re-parse the token.
  • Tertiary path (direct JWT): Local development or special clients may call extractTokenFromHeader / verifyToken from backend/src/lib/jwt.ts. The middleware honors Authorization: Bearer, an auth_token cookie, or Kratos JWTs, but will always reject if the exp claim 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/token and /api/auth/token/refresh (see backend/src/routes/token.ts). They are generated by generateKongJWT (backend/src/lib/jwt-kong.ts) and populate iss = "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’s jwt plugin on api-protected, ai-brain-route, agent-route-segregated, and document-rag-route verifies only the exp claim, so the backend MUST never issue tokens without that claim.
  • Environment dependency: The shared JWT_SECRET environment 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 in gateway/kong.yml is bound to studio-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.
  • HttpOnly cookies: Any cookies issued by the platform (ory_kratos_session, auth_token, session refresh cookies, etc.) MUST set HttpOnly, Secure, and SameSite=Strict to minimize XSS exposure. The backend expects an auth_token cookie when direct JWT fallback is triggered, so the client must mirror the cookie name exactly.
  • Kratos session handshake: When kratosAuthenticate calls kratos.toSession, it will drop authentication if x-session-token is present but invalid (i.e., a JWT). Token issuance should never embed Kratos session state inside x-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 from default allow := false. Every protected route must have an explicit allow rule.
  • 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 /api route is denied unless a new allow rule is added (e.g., /api/system and options requests are explicitly permitted).
  • Backend reinforcement: On top of Kong, the backend invokes checkAuthorization (backend/src/lib/opa.ts) through the authorizeWithOPA middleware. For critical endpoints, requireRole still exists as a secondary check.
  • Role consistency: Backend Prisma models limit role to '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 to api-protected or 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 (checkAuthorization returns false). Systems must keep the OPA service healthy; the gateway routes rely on allow_on_error: false.

6. Guiding Constraints for New Features

  • Authenticate every new API route via authenticate, guard critical endpoints with authorizeWithOPA, and only add custom requireRole checks 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 Prisma role field stays accurate.
  • Token refreshes should always occur through /api/auth/token/refresh rather than reissuing cookies manually; the /token handler already issues a fresh 24-hour token and updates expires_in.
  • Any client consuming tokens must store them in memory or LocalStorage for 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.ts
  • backend/src/middleware/kratos-auth.ts
  • backend/src/lib/jwt.ts & backend/src/lib/jwt-kong.ts
  • backend/src/routes/token.ts
  • backend/src/lib/opa.ts
  • gateway/opa/policies/rbac.rego
  • gateway/kong.yml