diff --git a/docs/docs/security/rbac/cas-coverage-gaps.md b/docs/docs/security/rbac/cas-coverage-gaps.md
new file mode 100644
index 0000000000..e13c46cea8
--- /dev/null
+++ b/docs/docs/security/rbac/cas-coverage-gaps.md
@@ -0,0 +1,191 @@
+# CAS Coverage and Migration Gaps
+
+**Status:** Living inventory, last reviewed 2026-08-15.
+
+**CAS** means the CAIPE **Centralized Authorization Service** in
+`ui/src/lib/authz`. Compare-and-set is a separate mechanism used when publishing
+authorization reconciliation state.
+
+## Target state
+
+Runtime authorization decisions and relationship mutations should pass through
+CAS so every path gets the same:
+
+- product-policy pre-checks, including private-resource interaction rules;
+- OpenFGA capability mapping;
+- decision and mutation audit records;
+- cache invalidation after relationship changes;
+- fail-closed error behavior.
+
+```mermaid
+flowchart LR
+ BFF["BFF resource-scoped routes"] --> CAS["CAS"]
+ DA["Dynamic Agents chat"] --> CAS
+ WF["Workflow engine"] --> CAS
+ CAS --> FGA[(OpenFGA)]
+
+ GW["AgentGateway authz bridge"] -. "direct checks" .-> FGA
+ LEG["Legacy BFF gates"] -. "direct checks" .-> FGA
+ RAG["RAG server"] -. "direct checks and writes" .-> FGA
+ BOT["Slack and Webex routing"] -. "direct reads and writes" .-> FGA
+ MUT["Bootstrap, team, service-account mutations"] -. "direct writes" .-> FGA
+```
+
+Solid lines are CAS-backed. Dotted lines are migration gaps unless listed as an
+intentional exception below.
+
+## Current CAS coverage
+
+| Surface | CAS entry point | Notes |
+|---|---|---|
+| BFF resource decisions | `ui/src/lib/rbac/resource-authz.ts` | `requireResourcePermission`, `filterResourcesByPermission`, and related helpers use CAS by default. A test-injected `check` function deliberately bypasses CAS. |
+| Dynamic Agents chat execution | `ai_platform_engineering/dynamic_agents/src/dynamic_agents/auth/authz.py` | Sends the caller-bound decision to `/api/authz/v1/decisions` and fails closed if CAS is unavailable. |
+| Workflow authorization | `ui/src/lib/server/workflow-cas-authz.ts` | Uses in-process `authorize` and `authorizeMany`. |
+| Shareable-resource reconciliation | `ui/src/lib/rbac/openfga-owned-resources-reconcile.ts` | Agent, MCP server, credential, and other migrated lifecycles call `reconcileTupleDiff`. |
+| CAS tuple reconciliation | `ui/src/lib/authz/reconcile.ts` | Writes the OpenFGA diff, invalidates the CAS decision cache, and emits a reconciliation audit event. |
+
+## Active gaps
+
+### 1. AgentGateway MCP authorization
+
+`deploy/openfga/bridge/main.py` calls OpenFGA directly for gateway, MCP server,
+owner, agent, and tool capabilities.
+
+This is the highest-risk gap because it is a runtime data-plane enforcement
+point. It cannot safely call the existing public, subject-bound CAS endpoint:
+AgentGateway may consume the bearer and send only verified identity metadata to
+`ext_authz`.
+
+**Migration requirement:** add an authenticated internal CAS protocol that
+accepts only gateway-verified identity and trusted interaction context. Do not
+accept a caller-supplied subject header as proof of identity.
+
+### 2. Legacy BFF organization and admin gates
+
+The following helpers perform direct OpenFGA checks instead of calling CAS:
+
+- `requireRbacPermission` in `ui/src/lib/api-middleware.ts`;
+- `requireAdminSurfaceManage`, `requireBaselineAdminSurfaceRead`, and profile
+ helpers in `ui/src/lib/rbac/require-openfga.ts`;
+- `requireAgentUsePermission` in
+ `ui/src/lib/rbac/openfga-agent-authz.ts`;
+- direct `checkOpenFgaTuple` calls in route handlers and legacy RBAC helpers.
+
+The resource-scoped BFF decision may already use CAS while an outer, coarse
+organization gate still uses direct OpenFGA. That hybrid path is protected, but
+it produces two authorization implementations and inconsistent audit semantics.
+
+### 3. Slack and Webex authorization
+
+Direct-message agent selection calls `/api/user/check_agent_access`. That route
+applies the private-resource context rule locally, then uses the direct-OpenFGA
+`evaluateAgentAccess` helper.
+
+Channel and space paths also access OpenFGA directly:
+
+- Slack routing and auto-assignment:
+ `ai_platform_engineering/integrations/slack_bot/utils/slack_agent_routes.py`
+ and `slack_channel_auto_assign.py`;
+- Webex routing and auto-assignment:
+ `ai_platform_engineering/integrations/webex_bot/utils/webex_agent_routes.py`
+ and `webex_space_auto_assign.py`;
+- Slack/Webex admin synchronization writers in the bot admin API modules.
+
+**Migration requirement:** pass server-derived `surface` and
+`conversationKind` to CAS. Group paths must never fall back to a direct human
+owner grant.
+
+### 4. RAG authorization
+
+`ai_platform_engineering/knowledge_bases/rag/server/src/server/rbac.py`
+implements direct OpenFGA checks, list-objects calls, tuple reads, and tuple
+writes for data sources, knowledge bases, MCP tools, team capabilities, and
+organization administration.
+
+The BFF proxy may perform a CAS-backed resource check before forwarding, but
+the RAG server remains an independent policy implementation.
+
+### 5. Relationship mutations outside CAS
+
+Direct `writeOpenFgaTuples`, `writeOpenFgaTupleDiff`, and
+`deleteExactOpenFgaTuples` calls remain in these lifecycle families:
+
+- service-account create, scope, revoke, and cleanup;
+- team membership, team capabilities, archived-team cleanup, and identity sync;
+- Slack channel and Webex space routes, resources, teams, and defaults;
+- conversation sharing and implicit conversation grants;
+- login, bootstrap-admin, super-admin, and unlinked-service-account repair;
+- Tome administrator/data-steward reconciliation;
+- RBAC migrations, repair, and backfill paths.
+
+These mutations reach OpenFGA but skip CAS cache invalidation and the canonical
+`cas_reconcile` audit event. Product lifecycle writers should migrate to
+`reconcileTupleDiff`. Temporary probe grants should use an explicitly scoped CAS
+helper with guaranteed cleanup.
+
+## Intentional direct OpenFGA operations
+
+Not every direct call is a migration defect. These operations may remain direct
+when they are isolated from product authorization decisions:
+
+- OpenFGA store creation, model publication, and first-install seed tuples;
+- raw OpenFGA administration, graph inspection, explain diagnostics, and
+ self-check tooling;
+- read-only drift reports and migration planning;
+- the low-level OpenFGA adapter used internally by CAS.
+
+Mutation-capable administrative tools still require a CAS-backed meta-
+authorization gate and must identify their direct writes in audit logs.
+
+The legacy Dynamic Agents module
+`dynamic_agents/auth/openfga_authz.py` also calls OpenFGA directly, but the
+active chat routes import `dynamic_agents/auth/authz.py`, which uses CAS. Treat
+the legacy module as removal work, not an active enforcement gap.
+
+## Source snapshot
+
+The following counts are overlapping indicators, not a total number of unique
+gaps. They were measured on 2026-08-15:
+
+| Indicator | API route files |
+|---|---:|
+| Uses `requireRbacPermission` | 78 |
+| Uses a `require-openfga` admin/profile helper | 21 |
+| Uses `requireAgentUsePermission` | 5 |
+| Directly references `checkOpenFgaTuple` | 17 |
+| Directly references an OpenFGA tuple mutation helper | 30 |
+
+Reproduce the inventory from the repository root:
+
+```bash
+rg -l 'requireRbacPermission' ui/src/app/api -g '*.ts' -g '!**/__tests__/**' \
+ -g '!**/*.test.ts'
+rg -l 'requireAdminSurfaceManage|requireBaselineAdminSurfaceRead|requireUserProfileRead' \
+ ui/src/app/api -g '*.ts' -g '!**/__tests__/**' -g '!**/*.test.ts'
+rg -l 'requireAgentUsePermission' ui/src/app/api -g '*.ts' \
+ -g '!**/__tests__/**' -g '!**/*.test.ts'
+rg -l 'checkOpenFgaTuple' ui/src/app/api -g '*.ts' -g '!**/__tests__/**' \
+ -g '!**/*.test.ts'
+rg -l 'writeOpenFgaTuples|writeOpenFgaTupleDiff|deleteExactOpenFgaTuples' \
+ ui/src/app/api -g '*.ts' -g '!**/__tests__/**' -g '!**/*.test.ts'
+rg -n 'OPENFGA|openfga' ai_platform_engineering -g '*.py' -g '!**/test_*.py'
+```
+
+Review each match: imports, read-only diagnostics, CAS's own adapter, and test
+injection points are not product-policy bypasses.
+
+## Migration order
+
+1. Add an authenticated internal CAS transport for AgentGateway.
+2. Move `/api/user/check_agent_access` and the active bot decision paths to CAS.
+3. Move RAG data-plane decisions to CAS.
+4. Replace legacy BFF organization/admin gates with CAS actions.
+5. Route service-account, team, channel, space, and conversation mutations
+ through CAS reconciliation.
+6. Retire dead direct-OpenFGA modules and then review bootstrap/migration tools.
+
+## Related documentation
+
+- [CAS implementation architecture](../../specs/2026-06-06-cas-implementation/architecture.md)
+- [PDP coverage audit](./pdp-coverage-audit.md)
+- [OpenFGA permission evaluation](./openfga-permission-evaluation.md)
diff --git a/docs/docs/security/rbac/index.md b/docs/docs/security/rbac/index.md
index c625103a10..74785e3cf9 100644
--- a/docs/docs/security/rbac/index.md
+++ b/docs/docs/security/rbac/index.md
@@ -11,6 +11,7 @@ This is the canonical reference for how authentication and authorization work in
| Get the short end-to-end summary of the Comprehensive RBAC refactor, including Keycloak roles, AgentGateway, and OpenFGA | [Comprehensive RBAC Refactor](./comprehensive-rbac-refactor.md) |
| Understand how JWT identity and OpenFGA relationship checks work together | [JWT and OpenFGA](./jwt-and-openfga.md) |
| Understand exactly where OpenFGA union/computed permissions are evaluated, what gets stored vs. computed, and follow a worked end-to-end Probe-button example | [OpenFGA Permission Evaluation](./openfga-permission-evaluation.md) |
+| See which authorization decisions and relationship mutations still bypass CAS, why, and in what order to migrate them | [CAS Coverage and Migration Gaps](./cas-coverage-gaps.md) |
| Trace a request — login, OBO token-exchange, end-to-end Slack/Webex flow, Slack channel or Webex space → agent routing | [Workflows](./workflows.md) |
| Log in, exercise a role, verify a denial, link a Slack/Webex user, run the demo | [Usage](./usage.md) |
| Find the file that owns a specific piece of the auth path | [File map](./file-map.md) |
diff --git a/docs/docs/specs/2026-06-06-cas-implementation/architecture.md b/docs/docs/specs/2026-06-06-cas-implementation/architecture.md
index 2128436614..a67b446599 100644
--- a/docs/docs/specs/2026-06-06-cas-implementation/architecture.md
+++ b/docs/docs/specs/2026-06-06-cas-implementation/architecture.md
@@ -1,6 +1,7 @@
# CAS Architecture Diagrams
**Date:** 2026-06-07
+**Last reviewed:** 2026-08-15
**Companion to:** [`spec.md`](./spec.md) · [`research.md`](./research.md) · [`../2026-06-05-centralized-bff-authz-pdp-agnostic/solution-architecture.md`](../2026-06-05-centralized-bff-authz-pdp-agnostic/solution-architecture.md)
> One decision core, multiple transports, PDP-agnostic. Additive today; consumers migrate incrementally.
@@ -31,7 +32,7 @@ flowchart TB
AD --> P
end
- DA["Dynamic Agents — next"] -->|HTTP + user JWT| V1
+ DA["Dynamic Agents chat ✓ migrated"] -->|HTTP + user JWT| V1
RB["RAG · Slack · Webex — later"] -->|HTTP| V1
OFA --> STORE[("OpenFGA store")]
AU --> M[("audit_events — Mongo")]
@@ -43,7 +44,10 @@ flowchart TB
**Key points**
- The **OpenFGA adapter is private** to `lib/authz` (ESLint silo boundary). Swapping in Cedar/OPA later = a new adapter behind the same `PolicyEngine` / `PolicyAdmin` interfaces.
- The **bridge** stays data-plane (per-MCP-call `ext_authz`); it does **not** route through the BFF.
-- DA/RAG/bots are **not migrated yet** — only the in-process `workflow-runs` route consumes CAS today.
+- Dynamic Agents chat and the workflow engine use CAS. Standard BFF
+ resource-scoped helpers also use CAS by default.
+- RAG, bots, legacy BFF gates, and the bridge are not fully migrated. See the
+ [living CAS gap inventory](../../security/rbac/cas-coverage-gaps.md).
---
@@ -104,14 +108,14 @@ sequenceDiagram
```mermaid
flowchart LR
subgraph now["Today (additive)"]
- n1["workflow-runs route → CAS"]
- n2["legacy paths untouched
DA openfga_authz · RAG rbac · bridge"]
+ n1["workflow engine · DA chat
BFF resource helpers → CAS"]
+ n2["legacy paths remain
RAG · bots · bridge · coarse BFF gates"]
end
subgraph next["Incremental"]
- x1["DA → CAS HTTP
(delete openfga_authz, workflow_execution_authz)"]
+ x1["Internal CAS transport
for AgentGateway"]
x2["RAG → CAS"]
- x3["bots → CAS"]
- x4["bridge: align vocabulary/audit"]
+ x3["bots and legacy BFF gates → CAS"]
+ x4["relationship mutations
→ CAS reconcile"]
end
now --> next
```