Tasks: Enterprise RBAC for Slack and CAIPE UI
Input: Design documents from /docs/docs/specs/098-enterprise-rbac-slack-ui/
Prerequisites: plan.md (required), spec.md (36 FRs, 15 SCs, 8 user stories), research.md, data-model.md, contracts/, quickstart.md
Organization: Tasks are grouped by user story to enable independent implementation and testing. Tests are included only within the test-coverage improvement phase (FR-035).
Format: [ID] [P?] [Story] Descriptionโ
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (e.g., US1, US2)
- Include exact file paths in descriptions
Part A: Completed โ User Management & Slack Linking (FR-033, FR-025)
The following 7 phases (37 tasks) were implemented in the initial sprint. All tasks are marked
[x]. New phases in Part B reference these as prerequisites and mark overlapping tasks as already satisfied.
Phase A1: Keycloak Admin Client Extensions (Foundational)โ
Purpose: Add all missing Keycloak Admin API wrapper functions required by both FR-033 (user detail view) and FR-025 (Slack identity linking). These are blocking prerequisites for all downstream API routes and UI components.
- T-A001 [P] Add
searchRealmUsers(params)function with text search, enabled filter, and server-side pagination (first/max) inui/src/lib/rbac/keycloak-admin.ts - T-A002 [P] Add
countRealmUsers(params)function returning total user count for pagination controls inui/src/lib/rbac/keycloak-admin.ts - T-A003 [P] Add
getUserSessions(userId)function returning active sessions (for last login timestamp) inui/src/lib/rbac/keycloak-admin.ts - T-A004 [P] Add
getUserFederatedIdentities(userId)function returning IdP source array inui/src/lib/rbac/keycloak-admin.ts - T-A005 [P] Add
assignRealmRolesToUser(userId, roles)function (POST role-mappings/realm) inui/src/lib/rbac/keycloak-admin.ts - T-A006 [P] Add
removeRealmRolesFromUser(userId, roles)function (DELETE role-mappings/realm) inui/src/lib/rbac/keycloak-admin.ts - T-A007 [P] Add
updateUser(userId, data)function for enable/disable toggle (PUT user with partial body) inui/src/lib/rbac/keycloak-admin.ts - T-A008 [P] Add
listUsersWithRole(roleName, first?, max?)function for role-based filtering inui/src/lib/rbac/keycloak-admin.ts
Checkpoint: All Keycloak Admin Client functions are available. API route and UI work can begin.
Phase A2: User Story 6 โ BFF API Routes for User Management (FR-033)โ
Goal: Build server-side API routes that provide paginated, filterable user data from Keycloak and CRUD for roles/teams.
- T-A009 [US6] Rewrite
GET /api/admin/usersto usesearchRealmUsersfor Keycloak server-side pagination with 6 filters (search, role, team, IdP, Slack status, enabled) inui/src/app/api/admin/users/route.ts - T-A010 [P] [US6] Create
GET /api/admin/users/[id]returning full user profile (Keycloak user + roles + sessions + federated identities + Slack link status + teams from MongoDB) inui/src/app/api/admin/users/[id]/route.ts - T-A011 [P] [US6] Create
PUT /api/admin/users/[id]for enable/disable user viaupdateUserinui/src/app/api/admin/users/[id]/route.ts - T-A012 [P] [US6] Create
POST /api/admin/users/[id]/rolesfor assigning realm roles viaassignRealmRolesToUserinui/src/app/api/admin/users/[id]/roles/route.ts - T-A013 [P] [US6] Create
DELETE /api/admin/users/[id]/rolesfor removing realm roles viaremoveRealmRolesFromUserinui/src/app/api/admin/users/[id]/roles/route.ts - T-A014 [P] [US6] Create
POST /api/admin/users/[id]/teamsfor adding user to CAIPE team (MongoDBteam_kb_ownershipupdate) inui/src/app/api/admin/users/[id]/teams/route.ts - T-A015 [P] [US6] Create
DELETE /api/admin/users/[id]/teamsfor removing user from CAIPE team inui/src/app/api/admin/users/[id]/teams/route.ts
Checkpoint: All user management API routes functional.
Phase A3: User Story 6 โ UserManagementTab Component (FR-033)โ
Goal: Build the paginated user table with filter bar that replaces the inline user grid.
- T-A016 [US6] Create
UserManagementTabcomponent with paginated table structure (Name, Email, Roles badges, Teams, IdP, Slack status, Enabled) inui/src/components/admin/UserManagementTab.tsx - T-A017 [US6] Add filter bar to
UserManagementTab: text search, role multi-select, team multi-select, IdP dropdown, Slack status dropdown, enabled toggle inui/src/components/admin/UserManagementTab.tsx - T-A018 [US6] Add pagination controls to
UserManagementTab: page number, total count, prev/next buttons, 20 per page default inui/src/components/admin/UserManagementTab.tsx
Checkpoint: User table with filters and pagination renders correctly.
Phase A4: User Story 6 โ UserDetailModal Component (FR-033)โ
Goal: Build the modal dialog showing full user profile with inline editing for roles and teams.
- T-A019 [US6] Create
UserDetailModalbase with shadcn/ui Dialog, header section (name, email, avatar placeholder, account status toggle), and close action inui/src/components/admin/UserDetailModal.tsx - T-A020 [US6] Add Realm Roles section to
UserDetailModalwith list display, add role dropdown, remove button per role, save viaPOST/DELETE /api/admin/users/[id]/rolesinui/src/components/admin/UserDetailModal.tsx - T-A021 [US6] Add Teams section to
UserDetailModalwith list display, add team dropdown, remove button per team, save viaPOST/DELETE /api/admin/users/[id]/teamsinui/src/components/admin/UserDetailModal.tsx - T-A022 [US6] Add Per-KB Roles section (read-only) to
UserDetailModalparsingkb_reader:<id>,kb_ingestor:<id>,kb_admin:<id>from realm roles inui/src/components/admin/UserDetailModal.tsx - T-A023 [US6] Add Per-Agent Roles section (read-only) to
UserDetailModalparsingagent_user:<id>,agent_admin:<id>from realm roles inui/src/components/admin/UserDetailModal.tsx - T-A024 [US6] Add Identity & Account section to
UserDetailModalshowing IdP source, Slack link status, last login timestamp, account created date inui/src/components/admin/UserDetailModal.tsx
Checkpoint: Modal shows full user profile with inline editing for roles and teams.
Phase A5: User Story 6 โ Admin Page Integration (FR-033)โ
Goal: Wire UserManagementTab and UserDetailModal into the Admin page, replacing the inline user grid.
- T-A025 [US6] Replace inline user grid in
ui/src/app/(app)/admin/page.tsxwithUserManagementTabcomponent import and rendering - T-A026 [US6] Wire
UserDetailModaltoUserManagementTabrow clicks โ pass selected user ID, open modal, refresh table on save inui/src/app/(app)/admin/page.tsx
Checkpoint: FR-033 fully integrated. Admin UI User Management is server-side paginated with full profile modal.
Phase A6: User Story 5 โ Slack Identity Linking Enhancements (FR-025)โ
Goal: Enhance the existing Slack identity linking flow with consumed nonce flag, Slack DM confirmation via Slack Web API, and proper HTML success page.
- T-A027 [US5] Update
NonceDoctype to includeconsumedboolean field and update nonce validation to checkconsumed === falseinui/src/app/api/auth/slack-link/route.ts - T-A028 [US5] Add
slack_user_idquery parameter handling โ extract from URL, use to resolve Keycloak user for attribute storage inui/src/app/api/auth/slack-link/route.ts - T-A029 [US5] Add Slack Web API DM confirmation after successful linking โ use
SLACK_BOT_TOKENenv var to callchat.postMessagewith success message inui/src/app/api/auth/slack-link/route.ts - T-A030 [US5] Replace plain-text success response with HTML success page ("Your Slack account is linked!") in
ui/src/app/api/auth/slack-link/route.ts - T-A031 [US5] Update
identity_linker.pyto store nonces in MongoDB instead of in-memory dict โ use motor/pymongo async client with TTL index oncreated_atinai_platform_engineering/integrations/slack_bot/utils/identity_linker.py - T-A032 [US5] Add MongoDB TTL index creation for
slack_link_noncescollection (unique onnonce, TTL 600s oncreated_at) inai_platform_engineering/integrations/slack_bot/utils/identity_linker.py
Checkpoint: FR-025 identity linking flow is production-ready with MongoDB nonces, consumed flag, Slack DM, and HTML success page.
Phase A7: Polish & Cross-Cutting Concernsโ
Purpose: Loading/error states, accessibility, environment variable documentation, cleanup.
- T-A033 [P] Add loading skeleton and error boundary to
UserManagementTabโ show skeleton rows during fetch, error banner on API failure inui/src/components/admin/UserManagementTab.tsx - T-A034 [P] Add loading spinner and error states to
UserDetailModalโ show spinner during profile fetch, toast on save error inui/src/components/admin/UserDetailModal.tsx - T-A035 [P] Add ARIA labels, keyboard navigation (Escape to close modal, Tab through controls), and focus management to
UserDetailModalinui/src/components/admin/UserDetailModal.tsx - T-A036 [P] Document new environment variables (
SLACK_BOT_TOKENfor BFF,SLACK_LINK_BASE_URLfor bot) indeploy/rbac/.env.rbac.example - T-A037 Remove deprecated inline user grid code from
ui/src/app/(app)/admin/page.tsxand clean up unused imports
Checkpoint: Part A complete โ 37/37 tasks done.
Part B: New Workstreams โ Enterprise RBAC Expansion
These phases extend the initial work with full enterprise RBAC, CEL policy enforcement, Keycloak role unification, test coverage, user self-service, and admin tab policies. Where a Part B task overlaps with completed Part A work, it is marked
[x]with a cross-reference.
Phase 1: Setup (Shared Infrastructure)โ
Purpose: Deployment infrastructure for Keycloak and Agent Gateway dev environments
- T001 Create Keycloak dev docker-compose and realm config in deploy/keycloak/docker-compose.yml and deploy/keycloak/realm-config.json โ already exists: KC 26.3, caipe realm, port 7080
- T002 [P] Create Agent Gateway dev docker-compose and config in deploy/agentgateway/docker-compose.yml and deploy/agentgateway/config.yaml โ already exists: JWT+CEL, Keycloak JWKS
- T003 [P] Add Keycloak Admin API env vars to ui/.env.local (KEYCLOAK_URL, KEYCLOAK_REALM, KEYCLOAK_ADMIN_CLIENT_ID, KEYCLOAK_ADMIN_CLIENT_SECRET) โ already configured
- T004 [P] Add BOOTSTRAP_ADMIN_EMAILS env var to ui/.env.local for initial admin bootstrap (FR-024 bootstrap) โ implemented in auth-config.ts
- T005 [P] Add SLACK_BOT_TOKEN env var to ui/.env.local for BFF Slack DM posting (FR-025) โ done in Phase A6
- T006 Verify Keycloak realm roles exist (admin, chat_user, team_member, kb_admin, offline_access) per quickstart.md โ verified in realm-config.json
- T007 Configure Keycloak client mappers on caipe-ui client (realm roles โ realm_access, groups โ groups, org claim) per data-model.md โ mappers created via Keycloak Admin API
Checkpoint: Keycloak + AG dev environment running; UI can authenticate via Keycloak OIDC
Phase 2: Foundational (Blocking Prerequisites)โ
Purpose: Core RBAC types, CEL evaluators, audit logger, and middleware that ALL user stories depend on
- T008 Define RbacResource, RbacScope, RbacRole types in ui/src/lib/rbac/types.ts (extend existing with full permission matrix types) โ already defined
- T009 [P] Verify CEL evaluator (TypeScript) in ui/src/lib/rbac/cel-evaluator.ts โ confirm fail-closed semantics and shared context schema (FR-029) โ verified: fail-closed on error
- T010 [P] Verify CEL evaluator (Python canonical) in ai_platform_engineering/utils/cel_evaluator.py โ confirm fail-closed and shared context schema โ verified: fail-closed, json_to_cel
- T011 [P] Verify CEL evaluator mirrors in ai_platform_engineering/dynamic_agents/src/dynamic_agents/cel_evaluator.py and ai_platform_engineering/knowledge_bases/rag/server/src/cel_evaluator.py โ verified: both mirrors exist and match canonical
- T012 Implement Keycloak Authorization Services client (UMA ticket grant, response_mode=decision) in ui/src/lib/rbac/keycloak-authz.ts โ extend checkPermission() with caching (FR-022) โ already implemented with SHA256 cache
- T013 [P] Implement Keycloak Admin REST API client in ui/src/lib/rbac/keycloak-admin.ts โ extend with realm role CRUD, user search, user attributes, IdP mapper CRUD โ core functions done in Phase A1; extend for additional IdP mapper CRUD
- T014 Implement structured audit event logger in ui/src/lib/rbac/audit.ts โ logAuthzDecision() with MongoDB persistence (FR-005) โ already implemented
- T015 [P] Implement RBAC denied-action feedback in ui/src/lib/rbac/error-responses.ts โ formatUiDenial(), deniedApiResponse() (FR-004) โ already implemented
- T016 Implement requireRbacPermission() in ui/src/lib/api-middleware.ts โ dual Keycloak AuthZ + CEL evaluation from CEL_RBAC_EXPRESSIONS env (FR-022, FR-029) โ already implemented
- T017 [P] Implement buildRbacCelContext() in ui/src/lib/api-middleware.ts โ decode JWT, extract realm_access.roles, build standard CEL context schema โ already implemented
- T018 [P] Add bootstrap admin detection to ui/src/lib/auth-config.ts โ isBootstrapAdmin() checks BOOTSTRAP_ADMIN_EMAILS env var โ already implemented
- T019 Merge Keycloak realm_access.roles into groups array in JWT callback in ui/src/lib/auth-config.ts โ ensures isAdminUser() checks both IdP groups and realm roles โ already implemented
- T020 [P] Implement useRbacPermissions hook in ui/src/hooks/useRbacPermissions.ts โ fetch GET /api/rbac/permissions, expose hasPermission(resource, scope) (FR-004) โ already implemented
- T021 Implement GET /api/rbac/permissions BFF endpoint in ui/src/app/api/rbac/permissions/route.ts โ return user's effective permissions from Keycloak AuthZ โ already implemented
Checkpoint: Foundation ready โ RBAC types, CEL evaluators, audit, middleware, and permissions hook all functional
Phase 3: User Story 1 โ Organization Administrator Governs Capabilities (Priority: P1)โ
Goal: Deliver a single enterprise-grade permission model enforcing same allow/deny across Slack and UI for all FR-008 entry points.
Independent Test: Define roles, assign users, confirm identical allow/deny outcomes for the same person in Slack vs UI for the same protected actions.
Implementationโ
- T022 [US1] Create permission matrix document listing all FR-008/FR-014 entry points in docs/docs/specs/098-enterprise-rbac-slack-ui/permission-matrix.md โ created with all 9 components, roles, scopes, PDP mapping
- T023 [US1] Model permission matrix as Keycloak resources and scopes in deploy/keycloak/realm-config.json โ one resource per component (admin_ui, slack, supervisor, rag, tool, mcp, a2a, sub_agent, skill) with applicable scopes โ already configured in realm-config.json
- T024 [US1] Create Keycloak role-based policies in realm-config.json โ map each realm role (admin, chat_user, team_member, kb_admin) to permitted resource#scope combinations โ already configured (admin-role-policy, chat-user-role-policy, etc.)
- T025 [P] [US1] Add RBAC enforcement to admin stats API route in ui/src/app/api/admin/stats/route.ts โ requireRbacPermission(session, 'admin_ui', 'view') โ added
- T026 [P] [US1] Add RBAC enforcement to admin teams API routes in ui/src/app/api/admin/teams/ โ view (all), create/delete (admin only) โ added to all 4 route files
- T027 [P] [US1] Add RBAC enforcement to RAG proxy routes in ui/src/app/api/rag/ โ requireRbacPermission for kb.query, kb.ingest, kb.admin scopes โ tools already enforced; added to [...path] proxy and kb proxy
- T028 [P] [US1] Add RBAC enforcement to conversation routes โ requireConversationAccess + Keycloak permission checks โ added supervisor#invoke to POST create conversation and POST add message
- T029 [US1] Document composition/precedence with ASP tool policy in permission-matrix.md โ FR-012 alignment (deny wins) โ included in permission-matrix.md ยง Composition with ASP
- T030 [US1] Configure Agent Gateway CEL policy rules in deploy/agentgateway/config.yaml โ mirror 098 matrix rows for MCP tool invocation, A2A, agent dispatch (FR-013) โ already configured with admin, RAG, team, dynamic agent, and general MCP CEL rules
Checkpoint: Permission matrix published (SC-001), BFF and AG enforce consistent allow/deny for 5+ personas
Phase 4: User Story 5 โ OBO Token Exchange & Bot Delegation (Priority: P1)โ
Goal: Slack/Webex bot obtains OBO token scoped to the commanding user; every downstream agent/tool call is authorized as that user.
Independent Test: A user with limited permissions issues a Slack command; bot gets OBO token; agent invokes tool via AG. Verify JWT sub=user, act=bot; AG enforces user's scope.
Implementationโ
- T031 [US5] Enable token-exchange feature on Keycloak realm in deploy/keycloak/realm-config.json โ caipe-slack-bot client configured with token-exchange
- T032 [US5] Create caipe-bot client (confidential, service account enabled) in realm-config.json โ grant token-exchange permission for caipe-ui client โ already configured
- T033 [US5] Implement OBO token exchange utility in ai_platform_engineering/integrations/slack_bot/utils/obo_exchange.py โ RFC 8693 via Keycloak token endpoint โ already implemented
- T034 [P] [US5] Implement Keycloak Admin API client for Slack bot in ai_platform_engineering/integrations/slack_bot/utils/keycloak_admin.py โ user attribute ops, user lookup โ already implemented
- T035 [P] [US5] Implement Keycloak AuthZ Services client for Slack bot in ai_platform_engineering/integrations/slack_bot/utils/keycloak_authz.py โ PDP queries โ already implemented
- T036 [US5] Implement RBAC enforcement middleware for Slack bot in ai_platform_engineering/integrations/slack_bot/utils/rbac_middleware.py โ check Keycloak AuthZ before forwarding to supervisor โ already implemented
- T037 [US5] Implement structured audit logger for Slack bot in ai_platform_engineering/integrations/slack_bot/utils/audit.py โ consistent with BFF audit format (FR-005) โ already implemented
- T038 [US5] Wire OBO JWT forwarding through A2A delegation chain in ai_platform_engineering/multi_agents/platform_engineer/protocol_bindings/a2a/agent_executor.py โ carry originating user principal (FR-019) โ added OBO token extraction from metadata and forwarding to agent.stream()
- T039 [US5] Integrate identity linking + OBO + RBAC middleware into Slack bot entry point in ai_platform_engineering/integrations/slack_bot/app.py โ wired OBO exchange into _rbac_enrich_context
Checkpoint: OBO token exchange demonstrated end-to-end (SC-008); AG accepts OBO token, rejects out-of-scope (SC-007)
Phase 5: User Story 7 โ RAG Server Keycloak + Per-KB Access Control (Priority: P1)โ
Goal: RAG server validates Keycloak JWTs directly and enforces per-KB access control, providing defense-in-depth.
Independent Test: Two KBs; user with kb_reader:kb-team-a sees only kb-team-a results; admin sees both; no per-KB role sees nothing.
Implementationโ
- T040 [US7] Extend KeycloakRole constants and KbPermission model in ai_platform_engineering/knowledge_bases/rag/common/src/common/models/rbac.py โ add Keycloak realm role mapping (adminโadmin, kb_adminโingestonly, chat_userโreadonly) โ already implemented
- T041 [US7] Implement Keycloak JWT realm role mapper in ai_platform_engineering/knowledge_bases/rag/server/src/server/rbac.py โ map_keycloak_roles_to_rag_role() with fallback to group-based assignment (FR-026) โ determine_role_from_keycloak_roles() implemented
- T042 [US7] Implement per-KB role parser in rbac.py โ extract
kb_reader:<id>,kb_ingestor:<id>,kb_admin:<id>from JWT roles claim; handle wildcards (kb_reader:*) โ extract_kb_permissions_from_roles() implemented - T043 [US7] Implement get_accessible_kb_ids() with CEL evaluation in rbac.py โ combine per-KB roles + team ownership (TeamKbOwnership MongoDB) + global role override (FR-027, FR-029) โ already implemented with CEL + MongoDB
- T044 [US7] Implement inject_kb_filter() for /v1/query endpoint in rbac.py โ query-time datasource_id filtering; fail-closed if MongoDB unavailable โ already implemented
- T045 [US7] Wire per-KB access dependencies into KB endpoints in ai_platform_engineering/knowledge_bases/rag/server/src/server/restapi.py โ /v1/query, /v1/ingest, KB admin endpoints โ require_kb_access() dependency available
- T046 [US7] Add UserContext.kb_permissions field in common/models/rbac.py โ carries resolved per-KB permissions through request lifecycle โ already in UserContext model
Checkpoint: Per-KB access enforced (SC-010, SC-011); backward compatible with non-Keycloak tokens
Phase 6: User Story 8 โ Dynamic Agent RBAC + CEL Policy (Priority: P1)โ
Goal: Dynamic agents governed by Keycloak RBAC with CEL evaluation; MCP calls route through AG.
Independent Test: Create two agents (team, global); agent_user role grants invoke; admin sees all; deepagent MCP calls via AG denied when user lacks tool role.
Implementationโ
- T047 [US8] Extend access.py with CEL-based evaluation in ai_platform_engineering/dynamic_agents/src/dynamic_agents/auth/access.py โ replace can_view_agent/can_use_agent with CEL expressions using standard context schema (FR-028, FR-029) โ already implemented with _agent_cel_context
- T048 [US8] Extend auth.py with Keycloak role mapper in ai_platform_engineering/dynamic_agents/src/dynamic_agents/auth/auth.py โ extract per-agent roles (
agent_user:<id>,agent_admin:<id>) from JWT โ realm roles extracted via _realm_roles_from_claims in access.py - T049 [US8] Implement Keycloak resource sync on agent create/delete in ai_platform_engineering/dynamic_agents/src/dynamic_agents/models.py โ create/delete Keycloak resource (type: dynamic_agent, scopes: view/invoke/configure/delete); clean up dangling roles (FR-028) โ KeycloakSyncService in services/keycloak_sync.py
- T050 [US8] Wire OBO JWT forwarding through deepagent LangGraph runtime in ai_platform_engineering/dynamic_agents/src/dynamic_agents/services/agent_runtime.py โ attach Authorization: Bearer on outbound MCP requests to AG (FR-030) โ obo_jwt field in UserContext, forwarded via auth.py
- T051 [US8] Update agent listing endpoint to use CEL-filtered query โ GET /api/v1/agents returns only agents the user can access per CEL evaluation โ CEL filtering in routes/agents.py using can_view_agent
- T052 [US8] Configure AG CEL policy rules for dynamic agent MCP tools in deploy/agentgateway/config.yaml โ deny when user lacks tool scope โ already configured: dynamic_agent_ prefix rules
Checkpoint: Three-layer RBAC enforced (SC-012); CEL used at all enforcement points (SC-013); MCP calls via AG (SC-007)
Phase 7: User Story 2 โ End User Sees Only What They Are Allowed to Use (Priority: P2)โ
Goal: UI screens and Slack commands reflect user permissions; admin destinations hidden for non-admins.
Independent Test: Walk through representative flows for 5 personas; visible options match authorization matrix.
Implementationโ
- T053 [US2] Add AdminTabKey union type and AdminTabGatesMap type to ui/src/lib/rbac/types.ts โ added AdminTabKey, AdminTabGatesMap, AdminTabPolicy
- T054 [US2] Create admin_tab_policies MongoDB seed data with default CEL expressions in ui/src/app/api/rbac/admin-tab-gates/route.ts โ 12 tabs: users/teams/skills/metrics/health (true), roles/slack/feedback/nps/stats/audit_logs/policy ('admin' in user.roles)
- T055 [US2] Implement GET /api/rbac/admin-tab-gates BFF endpoint in ui/src/app/api/rbac/admin-tab-gates/route.ts โ load policies from MongoDB, build CEL context from JWT, evaluate per-tab, apply feature-flag conjunctions (feedbackEnabled, npsEnabled, auditLogsEnabled)
- T056 [US2] Implement PUT /api/rbac/admin-tab-gates BFF endpoint (admin only) in same route.ts โ validate CEL expression, upsert into admin_tab_policies
- T057 [US2] Create useAdminTabGates React hook in ui/src/hooks/useAdminTabGates.ts โ call GET /api/rbac/admin-tab-gates, return gates map, loading, error, refresh
- T058 [US2] Refactor admin page in ui/src/app/(app)/admin/page.tsx โ replace isAdmin && tab checks with
gates.<tab_key>&&; update VALID_TABS filtering based on gates; keep isAdmin prop for write-mode in child components - T059 [P] [US2] Update AuthGuard in ui/src/components/auth-guard.tsx โ ensure basic auth check (no admin role check, just authenticated) โ already implemented correctly
- T060 [US2] Add Slack bot command filtering โ bot lists only commands the user's Keycloak roles permit; denied commands show "You don't have permission" (FR-004) โ require_permission decorator in rbac_middleware.py
Checkpoint: Non-admin users see only permitted admin tabs; CEL policies configurable in MongoDB; Slack commands filtered
Phase 8: User Story 3 โ Team Maintainer Configures Scoped RAG Tools (Priority: P2)โ
Goal: Team leads create and update custom RAG tools scoped to their team's approved datasources.
Independent Test: Two teams; maintainer on team A edits only team A's tools; cannot modify team B's; unauthorized users cannot edit any.
Implementationโ
- T061 [US3] Add team-scoped authorization to RAG tool CRUD routes in ui/src/app/api/rag/ โ requireRbacPermission + team ownership check via getUserTeamIds() โ assertTeamAccess in tools/route.ts and [toolId]/route.ts
- T062 [US3] Add team context to RAG tool creation โ new tools inherit team_id from creator's team; datasource bindings scoped to team-allowed KBs โ POST requires team_id, blocks cross-team creation
- T063 [US3] Update KB management pages in ui/src/app/(app)/knowledge-bases/ โ hide edit affordances for non-team-members; show read-only for others โ IngestView, OntologyGraphSigma, OntologyNodeDetailsCard: edit buttons hidden (not just disabled) when user lacks INGEST/DELETE permissions; MCPToolsView already hides via canEdit
- T064 [US3] Add team-scoped RAG tool rows to permission matrix in permission-matrix.md โ document which IdP groups map to team RAG tool admin for representative teams (SC-005) โ documented in permission-matrix.md
Checkpoint: Team-scoped RAG tools enforced (SC-005); cross-team editing blocked
Phase 9: User Story 6 โ Admin UI RBAC Management (Priority: P2)โ
Goal: Administrators manage roles, group mappings, and team assignments from CAIPE Admin UI without Keycloak Console access.
Independent Test: Admin creates a custom role, maps an AD group to it, assigns to a team โ all from CAIPE UI. User in that AD group gets the role in JWT. Cannot delete built-in roles.
Implementationโ
- T065 [US6] Implement GET/POST /api/admin/roles route in ui/src/app/api/admin/roles/route.ts โ list all realm roles (Keycloak Admin API), create new roles; mark built-in roles
- T066 [US6] Implement DELETE /api/admin/roles/[name] route in ui/src/app/api/admin/roles/[name]/route.ts โ block deletion of built-in roles (admin, chat_user, team_member, kb_admin, offline_access)
- T067 [US6] Implement GET/POST /api/admin/role-mappings route in ui/src/app/api/admin/role-mappings/route.ts โ CRUD for IdP group-to-role mappers via Keycloak Admin API (createGroupRoleMapper)
- T068 [US6] Implement DELETE /api/admin/role-mappings/[id] route in ui/src/app/api/admin/role-mappings/[id]/route.ts
- T069 [US6] Implement POST /api/admin/teams/[id]/roles route in ui/src/app/api/admin/teams/[id]/roles/route.ts โ assign Keycloak roles to a team; update MongoDB team document with keycloak_roles โ uses PUT
- T070 [US6] Build RolesAccessTab component in ui/src/components/admin/RolesAccessTab.tsx โ tabs for Realm Roles (list, create, delete), Group Mappings (list, create, delete), Team Roles (per-team assignment)
- T071 [P] [US6] Build CreateRoleDialog component in ui/src/components/admin/CreateRoleDialog.tsx
- T072 [P] [US6] Build GroupRoleMappingDialog component in ui/src/components/admin/GroupRoleMappingDialog.tsx
- T073 [US6] Build UserDetailModal component in ui/src/components/admin/UserDetailModal.tsx โ full profile (realm roles, teams, per-KB roles, per-agent roles, IdP source, Slack link, account status, last login) with inline editing (FR-033) โ completed in Phase A4
- T074 [US6] Build UserManagementTab with full filter bar in ui/src/components/admin/UserManagementTab.tsx โ text search, role filter, team filter, IdP filter, Slack link filter, account status filter; server-side pagination via Keycloak Admin API (FR-033) โ completed in Phase A3
Checkpoint: Admins manage all RBAC from CAIPE UI; built-in role deletion blocked; user detail modal with inline editing functional
Phase 10: Slack Identity Linking & Channel-to-Team Mapping (Priority: P2)โ
Goal: Slack users link accounts via OAuth; channels map to teams for automatic scope; admin dashboard for operational monitoring.
Independent Test: User links Slack account via OAuth; bot confirms in DM; admin sees linked status; channel mapped to team scopes bot commands.
Implementationโ
- T075 [US9] Implement Slack identity linker in ai_platform_engineering/integrations/slack_bot/utils/identity_linker.py โ generate linking URL with nonce + slack_user_id, 10min TTL (FR-025) โ completed in Phase A6
- T076 [US9] Implement POST /api/auth/slack-link BFF callback in ui/src/app/api/auth/slack-link/route.ts โ OIDC code exchange, store slack_user_id as Keycloak user attribute, post confirmation DM via Slack Web API, render success page (contract: slack-identity-linking-v1.md) โ completed in Phase A6
- T077 [US9] Create slack_link_nonces MongoDB collection with TTL index (10min expiry) โ nonce validation in BFF callback โ completed in Phase A6
- T078 [US9] Implement channel-to-team scope mapper in ai_platform_engineering/integrations/slack_bot/utils/channel_team_mapper.py โ resolve slack_channel_id โ team_id with 60s TTL cache (FR-031)
- T079 [US9] Wire channel scope into Slack bot command handling in ai_platform_engineering/integrations/slack_bot/app.py โ auto-scope to team's KBs/agents; deny with explanation if user lacks team_member role for that team
- T080 [P] [US9] Implement GET /api/admin/slack/users route in ui/src/app/api/admin/slack/users/route.ts โ Slack user bootstrapping data (link status, roles, teams, OBO counts, channel activity) via Keycloak Admin API + MongoDB slack_user_metrics (FR-032a)
- T081 [P] [US9] Implement GET/POST/DELETE /api/admin/slack/channel-mappings route in ui/src/app/api/admin/slack/channel-mappings/route.ts โ CRUD for slack_channel_id โ team_id in MongoDB (FR-032b)
- T082 [US9] Build SlackUsersTab component in ui/src/components/admin/SlackUsersTab.tsx โ full operational view per user: display name, Slack ID, link status, Keycloak username, roles, teams, timestamps, OBO metrics, action buttons (FR-032a)
- T083 [US9] Build SlackChannelMappingTab component in ui/src/components/admin/SlackChannelMappingTab.tsx โ browse Slack channels (Slack API), select team, create/view/remove mappings, flag stale mappings (FR-032b) โ manual channel ID; Slack API browser deferred
Checkpoint: Identity linking flow complete (FR-025); channel-to-team scoping works; admin dashboard operational (FR-032)
Phase 11: User Story 4 โ Audit & Compliance (Priority: P3)โ
Goal: Security reviewers can trace from permission matrix to sample audit records showing consistent allow/deny across channels.
Independent Test: Reviewer traces from matrix to audit records for both Slack and UI for same test users; no inconsistencies.
Implementationโ
- T084 [US4] Create authorization_decision_records MongoDB collection schema โ fields per data-model.md: ts, tenant_id, subject_hash, actor_hash, capability, component, resource_ref, outcome, reason_code, pdp, correlation_id โ implemented in ui/src/lib/rbac/audit.ts + mongodb.ts indexes
- T085 [US4] Implement GET /api/admin/audit route in ui/src/app/api/admin/audit/route.ts โ paginated query with filters (subject, component, outcome, date range); export CSV (FR-005) โ implemented as /api/admin/rbac-audit (JSON); CSV export deferred
- T086 [US4] Build AuditLogsTab component in ui/src/components/admin/AuditLogsTab.tsx โ filter by component, outcome, date; display human-readable entries; CSV export button โ exists for chat audit; RBAC audit separate at /api/admin/rbac-audit
- T087 [US4] Ensure Slack bot audit events use same format as BFF โ consistent subject_hash, capability keys, correlation_id pattern โ parity documented in audit.py
Checkpoint: Audit trail consistent across UI and Slack; reviewer can trace allow/deny decisions (SC-003)
Phase 12: Task Builder & Skills Gateway RBAC Unificationโ
Purpose: Extend three-layer RBAC model to Task Builder tasks and Skills Gateway skills (FR-028 updated)
- T088 Add task and skill resource types to Keycloak realm-config.json โ type: task (scopes: view/invoke/configure/delete), type: skill (scopes: view/invoke/configure/delete) โ skill resource scopes updated, a2a resource extended with configure/delete
- T089 [P] Implement Keycloak resource sync for Task Builder tasks โ create/delete resource on task create/delete โ keycloak-resource-sync.ts syncTaskResource() + wired into task-configs/route.ts POST/DELETE
- T090 [P] Implement Keycloak resource sync for Skills Gateway skills โ create/delete resource on skill create/delete โ syncSkillResource() + wired into agent-skills/route.ts POST/DELETE
- T091 Add per-task and per-skill realm role conventions to data-model.md โ
task_user:<id>,task_admin:<id>,skill_user:<id>,skill_admin:<id>โ documented in data-model.md - T092 Wire CEL-based access evaluation for task listing and invocation โ same pattern as dynamic agent access.py โ task-skill-realm-access.ts extractTaskAccessFromJwtRoles() + wired into task-configs GET
- T093 Wire CEL-based access evaluation for skill listing and invocation โ same pattern as dynamic agent access.py โ extractSkillAccessFromJwtRoles() + wired into agent-skills GET
Checkpoint: Task Builder and Skills Gateway use same RBAC model as dynamic agents (FR-028)
Phase 13: CEL-Based Admin Tab Policiesโ
Purpose: Replace hardcoded isAdmin tab checks with CEL-policy-driven tab visibility stored in MongoDB
- T094 Add AdminTabPolicy interface (tab_key, expression, description, is_system, updated_at, updated_by) to ui/src/lib/rbac/types.ts โ implemented in T053
- T095 Create GET handler in ui/src/app/api/rbac/admin-tab-gates/route.ts โ load admin_tab_policies from MongoDB; seed defaults if empty; decode JWT; evaluate CEL per tab; compose with feature flags; return gates map โ implemented in T055
- T096 Create PUT handler in ui/src/app/api/rbac/admin-tab-gates/route.ts โ admin-only; validate CEL expression parses; upsert into admin_tab_policies โ implemented in T056
- T097 Create useAdminTabGates hook in ui/src/hooks/useAdminTabGates.ts โ fetch GET /api/rbac/admin-tab-gates; defaults all gates to false (fail-closed); cache per session โ implemented in T057
- T098 Refactor admin page in ui/src/app/(app)/admin/page.tsx โ import useAdminTabGates; replace isAdmin && checks on TabsTrigger and TabsContent with
gates.<key>&&; validate activeTab against visible gates โ implemented in T058 - T099 Seed default CEL expressions for 12 admin tabs โ users/teams/skills/metrics/health: "true"; roles/slack/feedback/nps/stats/audit_logs/policy: "'admin' in user.roles" โ implemented in T054
Checkpoint: Admin tab visibility driven by CEL policies in MongoDB; new tabs require only a DB seed row
Phase 14: Test Coverage Improvement (FR-035)โ
Purpose: Fix all existing test failures and raise coverage to >= 70% statement coverage
- T100 Install pytest-asyncio and pytest-cov as dev dependencies in root pyproject.toml โ already present in [dependency-groups] dev
- T101 Add tests/ to testpaths in pyproject.toml โ already configured with asyncio_mode = "auto"
- T102 Fix supervisor async test failures (217 tests) โ mostly missing pytest-asyncio โ 602 tests pass, 32 skipped, 0 failures
- T103 [P] Fix UI test failures (218 tests across 25 suites) โ mock/import issues from recent refactoring โ fixed cel-js ESM mock, isBootstrapAdmin mocks, requireRbacPermission mocks, config.test.ts, auth-config.test.ts, admin-page.test.tsx; 109 suites pass, 2365 tests pass
- T104 Measure baseline supervisor coverage with pytest-cov and identify uncovered modules โ 15% overall (large codebase: 21k lines, many agent/KB modules not unit-testable without live services)
- T105 [P] Measure baseline UI coverage with Jest --coverage and identify uncovered modules โ 31% statement coverage; main gaps in components/ (large UI components), store/ (task-config, feature-flag), lib/ (keycloak-admin, keycloak-authz)
- T106 Write new supervisor tests targeting uncovered modules to reach >= 70% statement coverage โ deferred: requires mock infrastructure for MongoDB, Keycloak, LangGraph; current 15% baseline reflects large agent/KB surface that needs integration tests
- T107 [P] Write new UI tests targeting uncovered modules to reach >= 70% statement coverage โ deferred: current 31% baseline; main gaps are large React components requiring extensive mocking
Checkpoint: Zero failing tests in both suites; >= 70% statement coverage (SC-014)
Phase 15: User Self-Service RBAC Posture (FR-036)โ
Purpose: Display authenticated user's full RBAC posture in user system menu (read-only self-service)
- T108 Implement GET /api/auth/my-roles BFF route in ui/src/app/api/auth/my-roles/route.ts โ return realm roles, teams (from MongoDB), per-KB roles, per-agent roles, IdP source, Slack link status (contract: slack-identity-linking-v1.md)
- T109 Build RbacPosturePanel component in ui/src/components/user/ โ display realm roles (badges), teams (list), per-KB roles (table), per-agent roles (table), IdP source โ integrated as "My RBAC" tab in System dialog
- T110 Integrate RbacPosturePanel into user menu area in ui/src/components/layout/ (AppHeader or Sidebar) โ accessible from profile dropdown โ added as first tab in System dialog
Checkpoint: Non-admin users see their own RBAC posture without admin dashboard (SC-015)
Phase 16: Polish & Cross-Cutting Concernsโ
Purpose: Documentation, operator guide, API reference, and final validation
- T111 [P] Create API documentation for Admin & User Management domain in docs/docs/api/admin-user-management.md (FR-034) โ created with per-route auth details
- T112 [P] Create API documentation for RBAC & Roles domain in docs/docs/api/rbac-roles.md (FR-034) โ updated with admin-tab-gates, admin-tab-policies, audit-events
- T113 [P] Create API documentation for Slack Integration domain in docs/docs/api/slack-integration.md (FR-034) โ created
- T114 [P] Create API documentation for RAG & Knowledge Bases domain in docs/docs/api/rag-knowledge-bases.md (FR-034) โ created
- T115 [P] Create API documentation for Dynamic Agents & MCP domain in docs/docs/api/dynamic-agents-mcp.md (FR-034) โ created
- T116 [P] Create API documentation for Chat & Conversations domain in docs/docs/api/chat-conversations.md (FR-034) โ created
- T117 [P] Create API documentation for Platform domain in docs/docs/api/platform.md (FR-034) โ created with skills, catalog-api-keys, skill-hubs
- T118 [P] Create API documentation for CAIPE Supervisor Agent domain in docs/docs/api/supervisor-agent.md (FR-034) โ created with A2A JSON-RPC, agent-card, /tools, /metrics
- T119 Create docs/docs/api/index.md overview linking to all 8 domain documents (FR-034) โ rewritten as hub page
- T120 Create operator guide in docs/docs/specs/098-enterprise-rbac-slack-ui/operator-guide.md โ Keycloak realm setup, AG deployment, CEL policy rules, ASP composition, fail-closed behavior (FR-017) โ done 2026-03-26
- T121 Finalize permission matrix in permission-matrix.md โ ensure 100% FR-008 entry points covered (SC-001) โ done 2026-03-26: tasks/skills/chat/BFF/Keycloak cross-ref
- T122 Run quickstart.md validation โ verify full RBAC matrix with 5 personas (admin, chat_user, team_member, kb_admin, denied) per quickstart.md โ checklist added as quickstart ยง7; operators execute runs
- T123 Security hardening review โ verify default-deny everywhere (FR-002), fail-closed when Keycloak/AG unavailable, no privilege escalation in OBO chain (FR-019) โ security-review.md checklist
- T124 [P] Update spec.md and plan.md with final status and cross-references โ done 2026-03-26
Dependencies & Execution Orderโ
Phase Dependenciesโ
- Setup (Phase 1): No dependencies โ can start immediately
- Foundational (Phase 2): Depends on Phase 1 โ BLOCKS all user stories
- US1 (Phase 3): Depends on Phase 2 โ permission matrix and enforcement
- US5 (Phase 4): Depends on Phase 2 โ OBO requires Keycloak setup
- US7 (Phase 5): Depends on Phase 2 + Phase 3 (matrix) โ RAG server integration
- US8 (Phase 6): Depends on Phase 2 + Phase 3 (matrix) + Phase 4 (OBO for MCP routing)
- US2 (Phase 7): Depends on Phase 2 โ can start in parallel with P1 stories
- US3 (Phase 8): Depends on Phase 2 + Phase 5 (RAG per-KB access)
- US6 (Phase 9): Depends on Phase 2 + Phase 3 (roles in Keycloak); Phase A3-A5 satisfy UserManagementTab + UserDetailModal
- US9/Slack (Phase 10): Depends on Phase 4 (OBO) + Phase 9 (Admin UI roles); Phase A6 satisfies identity linking
- US4/Audit (Phase 11): Depends on Phase 3 (matrix) + Phase 4 (Slack audit)
- TB/SG (Phase 12): Depends on Phase 6 (dynamic agent RBAC pattern)
- CEL Tab Policies (Phase 13): Depends on Phase 2 (CEL evaluator + MongoDB) โ can start early
- Test Coverage (Phase 14): No story dependencies โ can start immediately and run in parallel
- Self-Service (Phase 15): Depends on Phase 2 (RBAC types) + Phase 9 (Admin user detail pattern)
- Polish (Phase 16): Depends on all desired stories being complete
Dependency Graphโ
Phase A1-A7 (Completed)
โโโ Phase 9 (T073, T074 satisfied)
โโโ Phase 10 (T075-T077 satisfied)
โโโ Phase A7 (polish satisfied)
Phase 1 (Setup)
โโโ Phase 2 (Foundational) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโ Phase 3 (US1: Matrix) โโฌโโ Phase 5 (US7: RAG) โ
โ โโโ Phase 6 (US8: Agents) โโโ โ
โ โโโ Phase 9 (US6: Admin UI) โ โ
โ โโโ Phase 11 (US4: Audit) โ โ
โโโ Phase 4 (US5: OBO) โโโโโผโโ Phase 10 (US9: Slack) โ โ
โ โโโ Phase 6 (US8: AG route) โ โ
โโโ Phase 7 (US2: UI gates) โ โ
โโโ Phase 8 (US3: RAG tools) โ Phase 5 โ โ
โโโ Phase 13 (CEL Tab Policies) โ Phase 7 โ โ
โโโ Phase 15 (Self-Service) โ Phase 9 โ โ
โ โ
Phase 12 (TB/SG) โ Phase 6 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
Phase 14 (Tests) โ independent, can start immediately โโโโโโโโโโโโโโโโโ
Phase 16 (Polish) โ all stories complete
Parallel Opportunitiesโ
- Phase 1: T001-T007 are all parallelizable after T001 completes
- Phase 2: T009-T011 (CEL verifiers), T013 (admin client), T015 (error responses), T018 (bootstrap admin), T020 (hook) are all parallel
- Phase 3-6 (P1 stories): US1 + US5 can start in parallel after Phase 2; US7 + US8 can start after US1
- Phase 7-10 (P2 stories): US2 can start independently; US6 + US3 + US9 can run after their dependencies
- Phase 14 (Tests): Fully independent โ can run in parallel with any phase
- Phase 16 (Docs): All 8 API docs (T111-T118) are parallelizable
Implementation Strategyโ
MVP First (P1 Stories โ Phases 1-6)โ
- Complete Phase 1: Setup (Keycloak + AG dev environment)
- Complete Phase 2: Foundational (types, CEL, audit, middleware)
- Complete Phase 3: US1 โ Permission matrix + BFF enforcement
- Complete Phase 4: US5 โ OBO token exchange + bot delegation
- Complete Phase 5: US7 โ RAG server per-KB access
- Complete Phase 6: US8 โ Dynamic agent RBAC + CEL
- STOP AND VALIDATE: All P1 stories (SC-001 through SC-013)
Incremental Deliveryโ
- Phases 1-6 โ P1 MVP (enterprise enforcement across all surfaces)
- Add Phase 7 (US2) โ Capability-based UI + CEL tab gates
- Add Phase 9 (US6) โ Admin RBAC management UI (UserManagementTab + UserDetailModal already done in Part A)
- Add Phase 8 (US3) โ Team-scoped RAG tools
- Add Phase 10 (US9) โ Slack channel mapping + admin dashboard (identity linking already done in Part A)
- Add Phase 11 (US4) โ Audit & compliance
- Add Phase 12-13 โ TB/SG unification + CEL tab policies
- Add Phase 14-15 โ Test coverage + self-service
- Phase 16 โ Polish, docs, operator guide
Parallel Team Strategyโ
With multiple developers:
- Team completes Phases 1-2 together
- Once Foundational is done:
- Developer A: US1 (matrix) + US5 (OBO) โ core enforcement
- Developer B: US7 (RAG) + US8 (agents) โ service integration
- Developer C: US6 (Admin UI) + US2 (UI gates) โ frontend
- Developer D: Phase 14 (test coverage) โ independent
- Phase 10 (Slack) needs A+C; Phase 16 (docs) can be split
Summaryโ
| Metric | Count |
|---|---|
| Part A tasks (completed) | 37 |
| Part B total tasks | 124 |
| Part B already satisfied by Part A | 9 (T003-T005, T007, T013, T018-T019, T073-T074, T075-T077) |
| Part B remaining tasks | 115 |
| Grand total unique tasks | 152 (37 completed + 115 new) |
| Setup phase | 7 (4 done) |
| Foundational phase | 14 (3 done) |
| US1 (P1) โ Matrix | 9 |
| US5 (P1) โ OBO | 9 |
| US7 (P1) โ RAG | 7 |
| US8 (P1) โ Agents | 6 |
| US2 (P2) โ UI gates | 8 |
| US3 (P2) โ RAG tools | 4 |
| US6 (P2) โ Admin UI | 10 (2 done) |
| US9 (P2) โ Slack | 9 (3 done) |
| US4 (P3) โ Audit | 4 |
| TB/SG unification | 6 |
| CEL tab policies | 6 |
| Test coverage | 8 |
| Self-service | 3 |
| Polish | 14 |
| Parallel opportunities | 45 tasks marked [P] |
| MVP scope | Phases 1-6 (52 tasks, 7 already done) |
Notesโ
- Part A IDs use
T-Annnprefix to distinguish from Part BTnnnIDs - [P] tasks = different files, no dependencies โ safe for parallel execution
- [Story] label maps task to specific user story for traceability
- Each user story is independently completable and testable
- Commit after each task or logical group
- Stop at any checkpoint to validate story independently
- CEL tab policies (Phase 13) overlap with US2 (Phase 7) โ T053-T058 are the same work as T094-T099; implement once in whichever phase comes first
- Phase 14 (test coverage) is independent and can start immediately
- Existing functions in
keycloak-admin.ts(searchRealmUsers, countRealmUsers, getUserSessions, getUserFederatedIdentities, assignRealmRolesToUser, removeRealmRolesFromUser, updateUser, listUsersWithRole) from Phase A1 are reused by Part B phases - Existing
slack-link/route.tsfrom Phase A6 has consumed nonce flag, Slack DM, and HTML success page - Existing
identity_linker.pyfrom Phase A6 uses MongoDB nonce store with TTL
Part C: Unified Audit Logs (FR-037)
Phase 17: Unified Agent/Human Auth & Tool Action Audit Logsโ
17.1 Python Audit Logger & Callbackโ
- T125: Create
ai_platform_engineering/utils/audit_logger.pyโlog_audit_event()writes toaudit_eventsMongoDB collection viamongodb_client.pysingleton [P] - T126: Create
ai_platform_engineering/utils/audit_callback.pyโAuditCallbackHandler(BaseCallbackHandler)withon_tool_start/end/error, gated byAUDIT_ENABLEDenv var [P]
17.2 Wire Audit into Supervisor & Agentsโ
- T127: Wire
AuditCallbackHandlerinto supervisoragent.pystream()method alongside tracing config - T128: Wire
AuditCallbackHandlerintoBaseLangGraphAgent.stream()alongside existingMetricsCallbackHandler - T129: Add
log_audit_event(type="agent_delegation")ina2a_remote_agent_connect.py_arunfinally block
17.3 BFF Dual-Write & Typesโ
- T130: Add
UnifiedAuditEvent,AuditEventType,AuditEventSource,UnifiedAuditOutcometypes toui/src/lib/rbac/types.ts - T131: Add
persistToUnifiedAuditEvents()dual-write toui/src/lib/rbac/audit.ts - T132: Add
"action_audit"toAdminTabKeytype
17.4 Unified API Endpointโ
- T133: Create
GET /api/admin/audit-eventsBFF route with filters (type, date, agent, tool, outcome, user, component, correlation_id) [P]
17.5 Unified Audit UI Tabโ
- T134: Create
UnifiedAuditTab.tsxcomponent โ filterable table, type badges (auth/tool/delegation), outcome badges, expandable detail rows, auto-refresh toggle [P] - T135: Add
action-audittab to adminpage.tsx(VALID_TABS, TabsTrigger, TabsContent, import)
17.6 Feature Flag & CEL Gateโ
- T136: Add
actionAuditEnabledconfig flag (envACTION_AUDIT_ENABLED, defaulttrue) toconfig.ts - T137: Add
action_audittoALL_TABS,DEFAULT_POLICIES, andTAB_FEATURE_FLAGSinadmin-tab-gates/route.ts - T138: Add
action_audit: falsetoEMPTY_GATESinuseAdminTabGates.ts
17.7 Spec & Documentationโ
- T139: Add FR-037 to
spec.md - T140: Document
GET /api/admin/audit-eventsendpoint indocs/docs/api/rbac-roles.md - T141: Append Phase 17 tasks to
tasks.md
Appendix: Next Implementation Checksโ
This appendix replaces the former root-level NEXT_STEPS.md scratch tracker.
Keep follow-up work here so the 098 task list remains the source of truth.
MCP tools in the Dynamic Agent editorโ
Current context:
AllowedToolsPicker.tsxis imported into the Dynamic Agent editor and fetches MCP servers from/api/mcp-servers?page_size=100.- The picker probes enabled MCP servers to discover available tools.
- The local seed config includes GitHub, ArgoCD, Jira, PagerDuty, and Knowledge Base MCP servers.
Verification tasks:
- Start the UI with
cd ui && npm run devsoinstrumentation.ts -> applySeedConfig()runs. - Wait for the seed log line:
[seed-config] Applied: X models, Y MCP servers, Z agents. - Verify MCP servers exist in MongoDB:
docker exec caipe-mongodb-dev mongosh admin -u admin -p changeme caipe \
--eval "db.mcp_servers.find().count()" - If the count is zero, debug seed-config loading in
ui/src/lib/seed-config.tsand startup logs. - If the API returns
401, verify the editor request is authenticated and the user has access to/api/mcp-servers. - If the dropdown is present but empty, inspect MCP probe and health-check failures for the configured servers.
- Confirm the Agent editor shows a "Select MCP Server" dropdown, expands a
server, lists tools, and persists selected tools into the agent
allowed_toolsmap.
Slack ReBAC channel/resource checksโ
Current context:
- Legacy channel-to-agent mapping UI/API is retired.
- Channel-to-team ownership is managed from each team's Slack Channels tab.
- Channel-to-agent, channel-to-tool, and channel-to-KB grants are managed from Admin UI -> Security & Policy -> OpenFGA ReBAC -> Slack Channels.
Verification tasks:
- Verify dynamic agents exist in MongoDB:
docker exec caipe-mongodb-dev mongosh admin -u admin -p changeme caipe \
--eval "db.dynamic_agents.find({}, {name: 1, visibility: 1}).toArray()" - Verify active Slack channel grants exist:
docker exec caipe-mongodb-dev mongosh admin -u admin -p changeme caipe \
--eval "db.slack_channel_grants.find({status:'active'}).toArray()" - Verify the admin user can access the relevant Admin UI tabs and OpenFGA ReBAC Slack Channels surface.
- Verify slack-bot/supervisor logs show Slack ReBAC checks during a test
message:
docker compose -f docker-compose.dev.yaml logs caipe-supervisor 2>&1 | grep "Slack ReBAC" - Create a test agent, grant a Slack channel access to it through OpenFGA ReBAC, and verify the Slack bot resolves and uses the grant.
Slack-bot conversation API proposalโ
Current context:
- Slack bot currently calls the supervisor directly through
SSEClient. - Next.js already has chat streaming and Dynamic Agent conversation endpoints,
including
/api/v1/chat/stream/startand/api/dynamic-agents/conversations. - A dedicated Slack-facing BFF API may be useful if the bot should rely on Next.js for conversation creation, RBAC context resolution, and stream lifecycle management.
Proposed endpoint tasks:
- Define and implement
POST /api/slack/conversationto start or resume a conversation. Request shape:{ slack_user_id, slack_channel_id, agent_id?, message? }. Response shape:{ conversation_id, thread_ts, status }. The route should resolve Slack identity, channel/team/resource access, RBAC, and OBO context without returning raw secrets to Slack. - Define and implement
GET /api/slack/conversation/:idto fetch conversation state for a Slack thread. - Define and implement
POST /api/slack/turnsto submit a Slack turn or message into the selected conversation. - Define and implement
GET /api/slack/start-streamas an SSE endpoint for streaming agent responses byconversation_idandturn_id. - Define and implement
POST /api/slack/resume-streamfor Slack stream resumption after reconnects. - Update
ai_platform_engineering/integrations/slack_bot/app.pyhandlers such ashandle_dm_message()andhandle_qanda_message()to call the BFF endpoints instead of calling the supervisor directly. - Add tests covering a Slack message that creates or resumes a conversation, starts a stream, posts streamed events to Slack, and submits a follow-up turn.
Example flow:
Slack user -> Bot receives @mention
-> POST /api/slack/conversation
<- { conversation_id, keycloak_user_id, agent_id, stream handle/context }
-> GET /api/slack/start-stream?conversation_id=...&turn_id=...
<- SSE events { type, data }
-> Bot posts streamed events to Slack
-> POST /api/slack/turns for follow-up messages