Skip to main content

Implementation Plan: Enterprise RBAC for Slack and CAIPE UI

Branch: 098-enterprise-rbac-slack-ui | Date: 2026-04-03 | Spec: spec.md
Last plan update: 2026-03-26 β€” documentation closure T120–T124 (operator guide, matrix, quickstart validation, security review, spec/plan cross-links)

Input: Feature specification from docs/docs/specs/098-enterprise-rbac-slack-ui/spec.md

Documentation status (final artifacts)​

ArtifactStatusNotes
operator-guide.mdDoneFR-017 β€” sourced from deploy/keycloak/realm-config.json, deploy/agentgateway/config.yaml, BFF/RAG code
permission-matrix.mdDoneFR-008/FR-014 β€” tasks, skills, chat/BFF, Keycloak cross-ref, export alignment note
security-review.mdDoneFR-002, FR-013, FR-019 β€” checklist tied to api-middleware.ts / keycloak-authz.ts
quickstart.md Β§7DoneSC-003 β€” five personas + optional regression
spec.mdUpdatedStatus, FR-014/FR-017/SC-001 cross-references

Summary​

Deliver enterprise RBAC consistent across Slack, CAIPE Admin UI, Supervisor, RAG, sub-agents, tools, skills, A2A, and MCP (FR-008, FR-014), grounded in IdP directory groups (Okta, Entra ID) federated through Keycloak (required OIDC broker and PDP), with OBO token exchange for end-to-end user identity delegation (FR-018–FR-021, absorbed from 093), Agent Gateway as the required MCP/A2A/agent data-plane gateway, RAG server Keycloak integration with per-KB access control (FR-026, FR-027) providing defense-in-depth enforcement at the data layer, dynamic agent RBAC with three-layer Keycloak resource + per-agent roles + MongoDB visibility (FR-028), CEL as the mandated policy engine at all enforcement points (FR-029), deepagent MCP routing through Agent Gateway (FR-030), Slack channel-to-team scope mapping (FR-031) so bot commands are automatically scoped to the linked team's KBs/agents/tools, and an Admin UI Slack Management Dashboard (FR-032) with full operational Slack user bootstrapping view and channel-to-team mapping manager.

Technical approach: Dual-PDP architecture:

  • Keycloak Authorization Services β€” PDP for UI/Slack paths (FR-022). The 098 permission matrix is modeled as Keycloak resources, scopes, and role-based policies. BFF and Slack bot call Keycloak AuthZ for every protected operation.
  • Agent Gateway β€” PDP for MCP/A2A/agent paths (FR-013). AG validates JWTs issued by Keycloak and applies CEL policy rules aligned with the 098 matrix.

Identity flow: Enterprise IdP (Okta/Entra) β†’ Keycloak (federation + claim mappers: groups β†’ roles at token issuance) β†’ JWT (sub, act, groups, roles, scope, org) β†’ consumed by all enforcement points. Slack identity linking stores slack_user_id as a Keycloak user attribute (no MongoDB dependency for the bot). OBO token exchange (RFC 8693) ensures downstream agents act as the user, not the bot.

Architecture reference: architecture.md

Technical Context​

Language/Version: Python 3.11+ (supervisor, agents, slack-bot); TypeScript / Next.js 16 (CAIPE UI, BFF API routes) Primary Dependencies:

  • Keycloak (required) β€” OIDC broker, token issuance, Authorization Services (PDP), OBO token exchange, identity link storage (user attributes)
  • Agent Gateway (required) β€” MCP/A2A/agent data-plane gateway, JWT validation, CEL policy
  • NextAuth.js β€” OIDC integration with Keycloak for UI sessions
  • Slack Bolt β€” Slack bot event handling
  • MongoDB β€” team/KB ownership assignments, app metadata, ASP tool policies Storage: Hybrid β€” Keycloak for authz policies (resources, scopes, permissions), realm roles, user attributes (slack_user_id); MongoDB for team/KB assignments, app metadata, operational state (FR-023) Testing: pytest (Python), Jest/npm test (UI), integration via make test / make caipe-ui-tests per constitution Target Platform: Linux containers (Kubernetes), browser clients Project Type: Web application (UI + BFF) with Slack bot integration and Python backend services Performance Goals: Keycloak AuthZ PDP decision p95 < 5 ms in-process (FR-022); permission propagation within 15 minutes of IdP group change (SC-002) Constraints: Default deny (FR-002); no secrets in repo; same canonical group claims across all paths (FR-012); OWASP-aligned UI; fail-closed when Keycloak or AG unavailable; Agent Gateway required for MCP/A2A/agent traffic (FR-013); permission matrix covers all FR-008/FR-014 components Scale/Scope: Multi-tenant org model (FR-020); permission matrix for Slack, Admin UI, Supervisor, RAG, sub-agents, tools, skills, A2A, MCP; team-scoped RAG tool admin (FR-009); OBO delegation chains (FR-018–FR-019)

Constitution Check​

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

PrincipleStatusNotes
I. Specifications as source of truthPassspec.md + this plan + architecture.md drive implementation
II. Agent-firstPassRBAC gates before supervisor/sub-agent dispatch; does not redefine graph semantics
III. MCP securityPassMCP tool list/invoke gated by Agent Gateway; least-privilege tool exposure via 098 matrix
IV. LangGraphN/ANo new graph requirement
V. A2APassA2A operations are matrix rows; protocol unchanged; OBO JWT forwarded through chain
VI. SkillsPassSkills in FR-014 scope where product exposes them
VII. Test-firstPassMatrix scenarios β†’ automated tests before merge; acceptance criteria from spec drive test cases
VIII. Structured documentationPassAll artifacts under this feature directory
IX. Security by defaultPassDeny by default, audit records, least privilege, no cross-team tool edits, HTTPS-only linking URLs
X. SimplicityPass (with justification)Keycloak is a new required service but consolidates OIDC brokering, OBO, PDP, and identity link storage β€” avoiding a custom caipe-authorization-server. AG is required upstream infrastructure for MCP/A2A security. See Complexity Tracking below.

Post–Phase 1 re-check: Design artifacts (data-model.md, contracts/rbac-authorization-v1.md) align with dual-PDP model. No unjustified new microservice beyond Keycloak (required broker) and AG (required gateway).

Post–Phase 10 addition (Session 2026-03-24): RAG server Keycloak JWT integration (FR-026) and per-KB access control (FR-027) added as Phase 10 / User Story 7 (P1). Defense-in-depth: BFF coarse AuthZ + RAG server fine-grained per-KB enforcement + query-time filtering. See architecture.md Β§ Map RAG RBAC to Keycloak.

Post–Phase 11 addition (Session 2026-03-25): Dynamic agent RBAC (FR-028), CEL as mandated policy engine (FR-029), and deepagent MCP routing through AG (FR-030) added as Phase 11 / User Story 8 (P1). Three-layer Keycloak resource + per-agent roles + MongoDB visibility model. CEL evaluators embedded in all services (AG, RAG, dynamic agents, BFF). See architecture.md Β§ Dynamic Agent RBAC.

Post–Phase 12 addition (Session 2026-03-25): Slack channel-to-team scope mapping (FR-031) and Admin UI Slack Management Dashboard (FR-032) added as Phase 12 / User Story 9 (P2). Slack channels act as team selectors (context only, not permission grants); Keycloak roles remain sole authority. Admin UI provides full operational view of Slack user bootstrapping (linking status, OBO counts, roles) and CRUD for channel-to-team mappings. Bot caches mappings with 60s TTL. See architecture.md Β§ Slack Channel RBAC.

Project Structure​

Documentation (this feature)​

docs/docs/specs/098-enterprise-rbac-slack-ui/
β”œβ”€β”€ plan.md # This file
β”œβ”€β”€ spec.md # Feature specification (36 FRs, 15 SCs, 8 user stories)
β”œβ”€β”€ architecture.md # Canonical architecture diagrams and flow tables
β”œβ”€β”€ research.md # Phase 0: decisions (PDP placement, IdP claims, AG mandate)
β”œβ”€β”€ data-model.md # Phase 1: entities (principals, roles, audit, Keycloak AuthZ model)
β”œβ”€β”€ quickstart.md # Phase 1: local verification of RBAC matrix
β”œβ”€β”€ contracts/
β”‚ └── rbac-authorization-v1.md # Internal authorization check contract (dual-PDP)
β”œβ”€β”€ checklists/
β”‚ └── requirements.md # Specification quality checklist
β”œβ”€β”€ permission-matrix.md # 098 permission matrix (FR-008, FR-014) β€” generated during implementation
β”œβ”€β”€ operator-guide.md # FR-017 deployment documentation β€” generated during implementation
└── tasks.md # Task list (/speckit.tasks output)

Source Code (repository root)​

ui/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ app/api/auth/[...nextauth]/route.ts # NextAuth + Keycloak OIDC
β”‚ β”œβ”€β”€ app/api/rbac/permissions/route.ts # BFF: user capabilities endpoint
β”‚ β”œβ”€β”€ app/api/admin/audit/route.ts # Audit query/export API
β”‚ β”œβ”€β”€ app/api/admin/roles/route.ts # Role CRUD (FR-024)
β”‚ β”œβ”€β”€ app/api/admin/roles/[name]/route.ts # Role detail/delete
β”‚ β”œβ”€β”€ app/api/admin/role-mappings/route.ts # Group-to-role mapping CRUD (FR-024)
β”‚ β”œβ”€β”€ app/api/admin/role-mappings/[id]/route.ts # Mapping delete
β”‚ β”œβ”€β”€ app/api/admin/teams/[id]/roles/route.ts # Team role assignment
β”‚ β”œβ”€β”€ app/api/admin/slack/users/route.ts # Slack user bootstrapping data (FR-032)
β”‚ β”œβ”€β”€ app/api/admin/slack/channel-mappings/route.ts # Channel-to-team mapping CRUD (FR-031, FR-032)
β”‚ β”œβ”€β”€ app/api/rag/ # RAG tool CRUD (team-scoped RBAC)
β”‚ β”œβ”€β”€ app/(app)/admin/ # Admin pages (RBAC-gated)
β”‚ β”œβ”€β”€ app/(app)/knowledge-bases/ # KB management (team-scoped)
β”‚ β”œβ”€β”€ lib/api-middleware.ts # BFF middleware (extend for Keycloak AuthZ)
β”‚ β”œβ”€β”€ lib/auth-config.ts # NextAuth OIDC config (Keycloak provider)
β”‚ β”œβ”€β”€ lib/rbac/
β”‚ β”‚ β”œβ”€β”€ keycloak-authz.ts # Keycloak Authorization Services client
β”‚ β”‚ β”œβ”€β”€ keycloak-admin.ts # Keycloak Admin REST API client (FR-024)
β”‚ β”‚ β”œβ”€β”€ types.ts # Permission matrix TypeScript types
β”‚ β”‚ β”œβ”€β”€ error-responses.ts # Denied-action feedback
β”‚ β”‚ └── audit.ts # Structured audit event logger
β”‚ β”œβ”€β”€ hooks/useRbacPermissions.ts # React hook for capability-based UI
β”‚ β”œβ”€β”€ components/auth-guard.tsx # Conditional rendering guard
β”‚ └── components/admin/
β”‚ β”œβ”€β”€ RolesAccessTab.tsx # Admin tab: roles, mappings, team assignments (FR-024)
β”‚ β”œβ”€β”€ CreateRoleDialog.tsx # New role dialog
β”‚ β”œβ”€β”€ GroupRoleMappingDialog.tsx # New group-to-role mapping dialog
β”‚ β”œβ”€β”€ SlackUsersTab.tsx # Slack user bootstrapping dashboard β€” full operational view (FR-032)
β”‚ └── SlackChannelMappingTab.tsx # Channel-to-team mapping CRUD manager (FR-031, FR-032)
└── tests/

ai_platform_engineering/
β”œβ”€β”€ knowledge_bases/rag/
β”‚ β”œβ”€β”€ server/src/server/
β”‚ β”‚ β”œβ”€β”€ rbac.py # Extended: Keycloak role mapper, per-KB access, query filter (FR-026, FR-027)
β”‚ β”‚ └── restapi.py # Extended: per-KB access dependencies on KB endpoints
β”‚ └── common/src/common/models/
β”‚ └── rbac.py # Extended: KeycloakRole constants, KbPermission model, UserContext.kb_permissions
β”œβ”€β”€ dynamic_agents/src/dynamic_agents/
β”‚ β”œβ”€β”€ auth/
β”‚ β”‚ β”œβ”€β”€ access.py # Extended: CEL-based access evaluation replacing can_view_agent/can_use_agent (FR-028, FR-029)
β”‚ β”‚ └── auth.py # Extended: Keycloak role mapper, per-agent role extraction from JWT (FR-028)
β”‚ β”œβ”€β”€ services/
β”‚ β”‚ └── agent_runtime.py # Extended: OBO JWT forwarding through LangGraph to MCP client (FR-030)
β”‚ └── models.py # Extended: Keycloak resource sync on agent create/delete (FR-028)
β”œβ”€β”€ integrations/slack_bot/
β”‚ β”œβ”€β”€ app.py # Slack bot entry (identity linking callback, RBAC middleware)
β”‚ └── utils/
β”‚ β”œβ”€β”€ keycloak_admin.py # Keycloak Admin API client (user attribute ops)
β”‚ β”œβ”€β”€ keycloak_authz.py # Keycloak AuthZ Services client (PDP)
β”‚ β”œβ”€β”€ identity_linker.py # Slack identity linking (FR-025)
β”‚ β”œβ”€β”€ obo_exchange.py # OBO token exchange (RFC 8693)
β”‚ β”œβ”€β”€ rbac_middleware.py # RBAC enforcement middleware
β”‚ β”œβ”€β”€ channel_team_mapper.py # Channel-to-team scope resolution + 60s TTL cache (FR-031)
β”‚ └── audit.py # Structured audit event logger
β”œβ”€β”€ multi_agents/platform_engineer/
β”‚ └── protocol_bindings/a2a/agent_executor.py # OBO JWT forwarding through delegation chain
β”œβ”€β”€ knowledge_bases/rag/
β”‚ β”œβ”€β”€ server/src/server/rbac.py # RAG server RBAC (extend for team/KB scope)
β”‚ └── common/src/common/models/rbac.py # RBAC data models
└── utils/

deploy/
β”œβ”€β”€ keycloak/
β”‚ β”œβ”€β”€ docker-compose.yml # Keycloak dev instance
β”‚ └── realm-config.json # Realm export: IdP brokers, mappers, roles, AuthZ
└── agentgateway/
β”œβ”€β”€ docker-compose.yml # AG dev instance
└── config.yaml # AG config with Keycloak OIDC + inline CEL rules (098 matrix)

Structure decision: Extend existing UI BFF (ui/src/lib/) and Slack bot (ai_platform_engineering/integrations/slack_bot/) with Keycloak AuthZ clients. New ui/src/lib/rbac/ directory for authorization utilities. Agent Gateway and Keycloak configs under deploy/. No new microservices β€” Keycloak and AG are external required infrastructure.

Complexity Tracking​

ViolationWhy NeededSimpler Alternative Rejected Because
Keycloak as required infrastructure (Principle X)Consolidates OIDC brokering, OBO token exchange, groups→roles mapping, Authorization Services (PDP), and Slack identity link storage into one proven componentCustom caipe-authorization-server rejected — would duplicate Keycloak AuthZ functionality; direct Okta/Entra without broker rejected — no OBO, no unified PDP (Session 2026-04-03)
Agent Gateway as required infrastructure (Principle X)Centralizes JWT validation + policy for all MCP/A2A/agent traffic; solves remote-MCP and auth-less-MCP gapsNo AG: leaves MCP/A2A without uniform auth gateway; per-agent JWT validation: inconsistent, harder to audit (Session 2026-04-01)
CEL as mandated policy engine (Principle X)Provides consistent, configurable, sandboxed policy evaluation across all enforcement points (AG, RAG, dynamic agents, BFF) with a shared context schemaCode-based checks rejected β€” not configurable, not auditable, inconsistent across services; OPA/Rego rejected β€” heavier runtime, different from AG's built-in CEL (Session 2026-03-25)

Generated artifacts (Phases 0–1)​

PhaseArtifactPurpose
0research.mdDecisions: PDP placement (Keycloak AuthZ), IdP claims, Slack parity, OBO split, AG mandate, hybrid store
1data-model.mdEntities: principals, roles, audit records, Keycloak AuthZ model, OBO tokens, team/KB assignments
1contracts/rbac-authorization-v1.mdDual-PDP authorization check contract (Keycloak AuthZ for UI/Slack; AG for MCP/A2A)
1quickstart.mdLocal verification with Keycloak + AG dev environment

Post–Phase 13 addition (Session 2026-03-25): Keycloak Role Unification​

Task Builder and Skills Gateway share the same RBAC granularity as Dynamic Agents (FR-028 updated): view/invoke/configure/delete scoped by roles and team visibility. They are user-created platform resources with the same lifecycle, so the three-layer model (Keycloak resource + per-resource realm roles + MongoDB visibility with CEL) applies uniformly.

Post–Phase 14 addition (Session 2026-03-25): Test Coverage Improvement (FR-035)​

Goal: Fix all existing test failures (218 UI + 217 supervisor) and raise both test suites to β‰₯70% statement coverage.

Baseline:

  • UI: 24.5% statement coverage, 218 tests failing across 25 suites (1,876 passing)
  • Supervisor: coverage unknown (pytest-cov not installed), 217 tests failing (mostly missing pytest-asyncio), 372 passing
StepDescriptionComponent
14aInstall pytest-asyncio, pytest-cov in supervisor workspacePython
14bAdd tests/ to testpaths in pyproject.tomlPython
14cFix supervisor async test failures (217 tests)Python
14dFix UI test failures (218 tests across 25 suites)TypeScript
14eWrite new tests targeting uncovered modules to reach β‰₯70%Both

No new CI gate β€” the existing make caipe-ui-tests and make test-supervisor pass/fail gates are sufficient. The goal is test quality improvement, not threshold enforcement.

Post–Phase 15 addition (Session 2026-03-25): User Self-Service RBAC Posture (FR-036)​

Goal: Display authenticated user's full RBAC posture in the user system menu (read-only).

The panel mirrors the admin user detail view (FR-033) but as a self-service read-only panel: Keycloak realm roles, CAIPE team memberships, per-KB roles (kb_reader:X, kb_ingestor:X, kb_admin:X), per-agent roles (agent_user:X, agent_admin:X), and identity provider source.

StepDescriptionComponent
15aAdd RBAC posture API route (/api/auth/my-roles)UI BFF
15bBuild user menu panel (realm roles, teams, per-KB, per-agent, IdP)UI
15cIntegrate into layout (AppHeader/Sidebar user menu area)UI

Workstream Summary (all phases)​

PhaseScopeFRsStatus
1–9Core RBAC, Keycloak, matrix, OBO, Admin UI, Slack, API docsFR-001–FR-034In progress (see tasks.md; partial merge on branch)
10RAG server Keycloak + per-KB accessFR-026, FR-027In progress / partial (RAG rbac.py CEL + Keycloak paths exist)
11Dynamic agent RBAC + CEL mandateFR-028–FR-030In progress / partial
12Slack channel-to-team mapping + Admin dashboardFR-031, FR-032In progress / partial
13Task Builder & Skills Gateway RBAC unificationFR-028 (updated)In progress (matrix + docs; full enforcement varies by route)
14Test coverage improvement (β‰₯70%)FR-035Open
15User self-service RBAC posture viewFR-036In progress / partial (/api/auth/my-roles, user menu)
DocsOperator guide, security review, matrix finalization, quickstart validationFR-017, FR-008, FR-014, SC-001, SC-003Done (2026-03-26, T120–T124)

Dependency Graph​

Phase 14 (Tests) ──────────────────────────────────────────────────┐
Phase 2 (Keycloak) ──┬── Phase 3 (Matrix) ──┬── Phase 10 (RAG) β”‚
β”‚ β”œβ”€β”€ Phase 11 (Agents) β”‚
β”‚ β”œβ”€β”€ Phase 13 (TB/SG) β”œβ”€ Phase 9 (API Docs)
β”œβ”€β”€ Phase 6 (OBO) β”œβ”€β”€ Phase 12 (Slack) β”‚
└── Phase 8 (Admin UI) ─┴── Phase 15 (Self) β”‚
β”‚
Phase 14 is independent β€” can start immediately β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Next step​

  1. Continue implementation from tasks.md until remaining FRs reach acceptance; run persona checklist in quickstart.md Β§7 before release candidates.
  2. Re-run /speckit.tasks if scope changes materially (tasks file already lists 100+ items across phases 1–15).

Paths (relative to repository root)

  • FEATURE_SPEC: docs/docs/specs/098-enterprise-rbac-slack-ui/spec.md
  • IMPL_PLAN: docs/docs/specs/098-enterprise-rbac-slack-ui/plan.md
  • SPECS_DIR: docs/docs/specs/098-enterprise-rbac-slack-ui