Skip to main content
Version: main 🚧

CAIPE RBAC Architecture (moved)

This document has moved. The canonical RBAC reference now lives under docs/docs/security/rbac/, split into four focused docs so you don't have to read end-to-end to find what you need.

If you want to…Go to
Get the big picture + JWT primer + threat modelSecurity β€Ί RBAC
See what each component does (Keycloak, UI, Supervisor, AgentGateway, Dynamic Agents)Architecture
Trace a request β€” login, OBO, end-to-end Slack flow, channel routingWorkflows
Bring up the stack, log in as test users, run the demo, troubleshootUsage
Find the file that owns a piece of the auth pathFile map

Important Runtime Note​

AgentGateway's current CEL runtime in this repo has a real limitation with JWT-backed role arrays:

  • has(jwt.sub) / has(jwt.realm_access.roles) can return false even when the field exists
  • "role" in jwt.realm_access.roles does not behave like normal CEL membership here
  • jwt.realm_access.roles.exists(...) can panic the gateway

The production-safe pattern is direct field access plus .contains(...), for example:

jwt.realm_access.roles.contains("admin_user")
jwt.realm_access.roles.contains("team_member:" + jwt.active_team)

That constraint is documented in the live architecture docs and reflected in deploy/agentgateway/config.yaml.

The old single-file version of this document is preserved in git history at the commit prior to the split (search the commit log for docs(security): split how-rbac-works.md).