Release 0.5.0 — Enterprise RBAC and OpenFGA Authorization
Released: 2026-05-26 Chart:
oci://ghcr.io/cnoe-io/charts/ai-platform-engineering:0.5.0Previous release: 0.4.18
Highlights
0.5.0 is a headline minor release that lands CAIPE's enterprise authorization foundation: a full cutover from legacy role-based access control to relationship-based access control (ReBAC) backed by OpenFGA, with Keycloak as the identity provider and an AgentGateway ext_authz bridge enforcing per-call MCP decisions. The release introduces a new Webex bot alongside ReBAC-aware Slack routing, an envelope-encrypted credential store and OAuth connector platform, and a hardened secrets bootstrap that fails loudly on dev placeholders instead of silently shipping insecure defaults. The entire authorization stack is opt-in and disabled by default — for a stock 0.4.18 deployment this is a drop-in upgrade with no values.yaml edits required. Operators who adopt RBAC get team-based access control, per-document RAG ACLs, channel-derived team binding for bots, and a redesigned admin UI for managing teams, identity-group sync, and onboarding defaults.
What's New
Identity & Authorization (OpenFGA ReBAC)
- OpenFGA ReBAC core, admin BFF, and admin UI — new
ui/src/lib/rbaclibrary (OpenFGA client, tuple builder, store, PDP, decision cache, role-mapping, group-sync, team/agent resolvers, Keycloak Admin REST helpers), the full admin BFF API surface, and admin UI components for teams and authorization management (#1526) - Auth foundation Helm charts — brand-new
keycloak,openfga,openfga-authz-bridge, andagentgatewaysubcharts, including Keycloak realm init, token-exchange and auth-reconcile jobs, the OpenFGA authorization model bootstrap, and the Python ext_authz bridge (#1496) - Shared MCP agent-auth library — new
mcp-agent-authpackage (JWT validation, caller-key derivation, OBO exchange, in-process JWKS cache, downstream token forwarder, PDP) wired uniformly into 13 agent MCP servers viaMCPAuthMiddleware(Spec 101) (#1524) - RAG ReBAC with per-document ACLs — OpenFGA-backed authorization for the RAG server, ACL propagation through every ingestor, per-document enforcement at retrieval time, and a userinfo cache for the OBO-validation hot path (#1525)
adminimpliesmember+ auto-provisioned Super Admins team — OpenFGA model bump so anyone with theadminrelation on a team satisfiesteam#memberchecks, removing the need to dual-write tuples; a Super Admins team is auto-provisioned for platform defaults (#1555)- Persisted onboarding defaults — default team and agent for new users stored in
platform_configand editable from the admin UI/BFF (#1558) - Admin-configurable discovery cache TTL — tune the Slack/Webex onboarding discovery cache from the admin UI (#1556)
Bots: Webex + Slack ReBAC
- New Webex bot integration — full
webex_botintegration (a2a client, app, identity linking, audit, hardening, Prometheus metrics) plus awebex-botHelm subchart, Dockerfile, and CI workflow (#1523) - Slack ReBAC additions — channel-team resolver, JIT identity linking, SSE OBO, runtime policy, and opt-in first-message channel onboarding for unmapped channels (#1523)
- Channel-derived team binding — replaces the single-team
active_teamJWT claim with a model that derives the authorizing team from the channel/context (Slack channel, Webex space, DM), correct for multi-team users by construction; adds personal DM commands across both bots (#1562)
Connections & Credentials
- Envelope-encrypted credential store + OAuth platform — MongoDB-backed envelope-encrypted credential storage with KMS-style data-key wrapping (AES-GCM with a master key), an OAuth connector platform (built-in providers, token refresh, state store, provider detection), and a Python credential-exchange client for agents; gated behind the
CAIPE_CREDENTIALS_ENABLEDfeature flag and disabled by default (#1497)
Dynamic Agents
- JWT/OBO auth + OpenFGA PDP gate — JWKS validation middleware, on-behalf-of token exchange, request-local token context, and a ReBAC PDP gate bring the dynamic-agents runtime to parity with the rest of the auth surface (#1499)
- MCP endpoint normalizer + self-heal — canonicalizes MCP URLs from bot configs (trailing slash,
/mcpsuffix, scheme inference), forwards request tokens via OBO, resolves credential refs, and adds probe + self-heal diagnostics (#1499) - Editor blocker hints + protected platform default agent — surfaces blocker hints in the agent editor and prevents deletion/misconfiguration of the platform default agent (#1559)
Supervisor
get_file_line_counttool — new tool the agent is prompted to call beforeread_file, so it reads large files in bounded ranges instead of pulling entire files into context (#1565)- User identity + JWT forwarding — opt-in
ENABLE_USER_INFO_TOOLcaptures user identity from the JWT (enabling theuser_infotool and JWT context middleware);FORWARD_JWT_TO_MCPforwards the user JWT as a Bearer token to HTTP/streamable-HTTP MCP connections. Both default tofalse(#1524)
Setup
- Expanded embeddings menu —
setup-caipe.shnow offers all 7EmbeddingsFactoryproviders, including AWS Bedrock, Cohere, and Voyage AI (the recommended embeddings provider for Anthropic Claude users) (#1538)
Bug Fixes
- rbac: scoped team admins can now edit, delete, and configure their own team — previously group admins could not modify anything within their own group (issue #1509, fixed in #1567)
- ui/slack: drop stale env-provided Slack default agent/team and surface a warning instead of silently honoring removed defaults (#1539)
- ui: use
users.conversationsfor Slack channel discovery to dodge Slack API rate limits (#1536) - chart/caipe-ui: include
workflow_configsin the app configmap so self-service workflows render correctly (#1549) - setup-caipe: pull the Ollama embedding model during setup so local embeddings work out of the box (#1553)
Security
This release is security-heavy by design — it ships the authorization stack and hardens the secrets bootstrap.
- Keycloak client-secret hardening — adds a reconcile pass that rotates dev placeholder secrets for the three confidential service-account clients (
caipe-platform,caipe-slack-bot,caipe-webex-bot) on every install/upgrade, a strict-mode gate (keycloak.strictClientSecrets, default off) that fails the install if any known dev placeholder still mints a token, ExternalSecrets support forcaipe-platform.OIDC_CLIENT_SECRET, and removal of 5 demo users with hardcoded passwords from the bundled realm config (#1518) - Kill BFF
admin/adminfallback + strict-mode gates — the BFF Keycloak Admin client no longer falls back toadmin/adminagainst/realms/master; production requires theclient_credentialspath against a confidential client and fails loudly otherwise. Adds MongoDB and NextAuth strict-mode gates, and auto-wiresKEYCLOAK_ADMIN_CLIENT_ID/SECRETfrom the same Secret the Keycloak chart writes (R1/R3/R4 of the May 2026 secrets audit) (#1519) - Envelope-encrypted credentials — credentials are stored with AES-GCM envelope encryption and KMS-style data-key wrapping; production installs must use
aws-kms(thelocal-cmkprovider is for non-production testing only) (#1497) - MongoDB strict-password gate — new
mongodb.auth.strictPasswords(default off) makeshelm install/upgradefail-fast whenauth.rootPasswordis left at a known placeholder such aschangeme - Dependency hardening — pin
aiohttp,websockets, and@aws-sdk/client-kmsto exact versions; bumpfastmcpto 3.3.1 and regenerate lock files; refresh stale MCPuv.lockfiles; remove fixable grype findings from container images; bumpprotobufandqs
Breaking Changes
There are no breaking Helm values changes — every key in the chart diff is additive, and the entire RBAC/OpenFGA/Keycloak/Webex stack ships disabled by default (tags.keycloak, tags.webex-bot, openfga.enabled, global.agentgateway.enabled, CAIPE_CREDENTIALS_ENABLED all default to false). For a stock 0.4.18 deployment, 0.5.0 is a drop-in upgrade.
One behavioral breaking change applies only if you were tracking pre-release 0.5.x builds or had a custom integration that read the active_team JWT claim:
active_teamJWT claim removed (#1562) — the single-team-per-tokenactive_teamclaim and all of its supporting code (heal routes, scope matrices, diagnostic invariants, env passthrough, cleanup script, team-scope Keycloak helpers) have been demolished and replaced with channel-derived team binding. Consequence if not updated: any external code that inspectedactive_teamon a CAIPE-issued JWT will no longer find the claim. Authorization is now derived from the channel/space/DM context of the request. No action is required for operators upgrading from0.4.18, since that release never issued the claim through this stack.
Known Issues
None known at this time.
Upgrade
helm upgrade ai-platform-engineering \
oci://ghcr.io/cnoe-io/charts/ai-platform-engineering \
--version 0.5.0 \
-f your-values.yaml
Upgrade Guide: 0.4.18 → 0.5.0
Overview
0.5.0 introduces the enterprise authorization foundation — OpenFGA ReBAC, Keycloak identity, AgentGateway ext_authz, a Webex bot, and an envelope-encrypted credential store. Despite the size of the release (112 commits), the upgrade is drop-in for existing 0.4.18 deployments: every new Helm value is additive with a working default, and all of the new authorization machinery is gated behind feature flags that default to disabled. You only need to edit values.yaml if you are opting into RBAC, the Webex bot, or the credential store.
Helm Values Changes
No keys were renamed, removed, or type-changed between 0.4.18 and 0.5.0. The only modified line is a comment reformat of the unchanged mongodb.auth.rootPassword: "changeme" default. Everything else is new optional configuration.
Breaking Changes
None. No breaking Helm values changes.
New Optional Fields
Chart toggles & global config
| Key | Default | Description |
|---|---|---|
tags.webex-bot | false | Enable the new Webex bot subchart |
tags.keycloak | false | Enable the bundled Keycloak identity provider |
openfga.enabled | false | Enable the OpenFGA relationship PDP |
openfgaAuthzBridge.enabled | false | Enable the AgentGateway ext_authz bridge |
global.image.channel | "" (auto) | Force the image repo channel (pre-release or release); empty auto-selects by appVersion |
global.agentgateway.enabled | false | Route MCP traffic through the AgentGateway proxy |
global.agentgateway.installIstioCrds | false | Install Istio CRDs (leave false if Istio is already present) |
global.agentgateway.proxyPort | 8080 | AgentGateway proxy listener port |
global.agentgateway.extAuth.* | disabled | ext_authz service name/namespace/port for OpenFGA decisions |
global.openfga.httpUrl | http://{{ .Release.Name }}-openfga:8080 | OpenFGA discovery URL for CAIPE components |
global.openfga.storeName | caipe-openfga | OpenFGA store name |
agentgateway.* (top level) | enabled: false | AgentGateway proxy image/config |
<agent>.mcp.agentgateway.enabled | false | Per-agent: route MCP calls through AgentGateway (with protocol: StreamableHTTP) |
Supervisor (global.config)
| Env Var | Default | Description |
|---|---|---|
ENABLE_USER_INFO_TOOL | false | Capture user identity from the JWT; enables the user_info tool and JWT context middleware |
FORWARD_JWT_TO_MCP | false | Forward the user JWT as a Bearer token to HTTP/streamable-HTTP MCP connections (requires ENABLE_USER_INFO_TOOL=true) |
CAIPE UI (caipe-ui.config / caipe-ui.keycloakAdminClient)
| Key | Default | Description |
|---|---|---|
keycloakAdminClient.secretName | caipe-platform-secret | Secret holding the Keycloak Admin REST client secret |
keycloakAdminClient.secretKey | OIDC_CLIENT_SECRET | Key within that Secret |
keycloakAdminClient.clientId | caipe-platform | Keycloak Admin REST client ID |
CAIPE_CREDENTIALS_ENABLED | false | Enable the Connections & Secrets credential store |
CREDENTIAL_STORE_BACKEND | mongodb-envelope | Credential storage backend |
CREDENTIAL_KEY_PROVIDER | local-cmk | Data-key provider (local-cmk for test, aws-kms for prod) |
CREDENTIAL_KMS_CMK_ID / CREDENTIAL_KMS_REGION | "" | AWS KMS CMK id/region when using aws-kms |
CREDENTIAL_BOOTSTRAP_OAUTH_CONNECTORS | false | Bootstrap global OAuth connectors from server env at startup |
OPENFGA_HTTP | "" | OpenFGA URL for relationship authorization (set after OpenFGA is installed) |
OPENFGA_STORE_NAME | caipe-openfga | OpenFGA store name |
OPENFGA_RECONCILE_ENABLED | false | Enable OpenFGA reconciliation |
KEYCLOAK_URL / KEYCLOAK_REALM | "" / caipe | Keycloak Admin API integration |
KEYCLOAK_RESOURCE_SERVER_ID | caipe-platform | Keycloak resource server id for resource/scope sync |
SLACK_WORKSPACE_ALIAS | CAIPE | Canonical Slack workspace namespace for ReBAC/routes |
SLACK_BOT_ADMIN_URL / SLACK_BOT_ADMIN_AUDIENCE | slack-bot URL / caipe-slack-bot-admin | Slack bot internal admin API used by the BFF |
WEBEX_BOT_ADMIN_URL / WEBEX_BOT_ADMIN_AUDIENCE | webex-bot URL / caipe-webex-bot-admin | Webex bot internal admin API |
WEBEX_THREAD_CONTEXT_* | true / 10 / 4000 | Webex thread-context window settings |
CAIPE_ORG_KEY / CAIPE_ORG_DISPLAY_NAME | caipe / CAIPE | Org namespace + display name |
Dynamic Agents (dynamic-agents.config)
| Env Var | Default | Description |
|---|---|---|
KEYCLOAK_URL | http://ai-platform-engineering-keycloak:8080 | In-cluster Keycloak service URL for JWKS fetch (override for external IdP) |
OIDC_ISSUER | "" | Browser-facing issuer baked into JWTs; falls back to deriving from KEYCLOAK_URL in dev |
CAIPE_CREDENTIALS_ENABLED | false | Enable the credential-exchange client |
CREDENTIAL_API_URL | caipe-ui /api/credentials | Credential exchange API endpoint |
USE_IMPERSONATION_TOKENS | false | Use impersonation tokens for downstream calls |
AGENT_GATEWAY_MCP_SERVER_IDS | jira | MCP server IDs routed through the AgentGateway backend |
Slack bot (slack-bot.config)
| Env Var | Default | Description |
|---|---|---|
SLACK_WORKSPACE_ALIAS | CAIPE | Canonical workspace namespace for ReBAC/routes |
SLACK_AGENT_ROUTES_MODE | db_prefer | Prefer UI-managed Slack routes, fall back to static config |
SLACK_AUTO_ASSIGN_UNMAPPED_CHANNELS | false | Opt-in first-message channel onboarding |
SLACK_DEFAULT_TEAM_SLUG / SLACK_DEFAULT_AGENT_ID | "" | Required when auto-assignment is enabled |
SLACK_ADMIN_API_ENABLED | false | Internal admin API for route status/reload/config sync |
SLACK_ADMIN_JWT_ISSUER / SLACK_ADMIN_JWT_AUDIENCE | "" / caipe-slack-bot-admin | OIDC issuer/audience for the admin API |
SLACK_ADMIN_ALLOWED_CLIENT_IDS | caipe-ui | Client IDs allowed to call the admin API |
New subcharts (entirely new value blocks)
| Block | Enabled by | Purpose |
|---|---|---|
webex-bot | tags.webex-bot=true | Webex spaces, identity linking, OpenFGA ReBAC |
keycloak | tags.keycloak=true | Identity provider, federation broker, RFC 8693 token exchange |
openfga | openfga.enabled=true | Relationship PDP (team/resource tuples) |
openfga-authz-bridge | openfgaAuthzBridge.enabled=true | Envoy ext_authz → OpenFGA Check bridge for AgentGateway |
Deprecated / Removed Keys
None. No keys were deprecated or removed in 0.5.0.
Data Migrations
- MongoDB: no destructive schema migration. New collections back the credential store (envelope-encrypted) and Slack/Webex route management; the credential store also adds indexes via
scripts/init-credential-mongo-indexes.ts. These are created lazily/on-demand and only when the corresponding feature is enabled. - OpenFGA: if you enable RBAC, the OpenFGA chart bootstraps the authorization model (
authorization-model.json) and creates thecaipe-openfgastore. Existing deployments have nothing to migrate — there was no prior OpenFGA store. - Keycloak: the Keycloak subchart is new in this release. Enabling it initializes the
caiperealm, token-exchange clients, and (optionally) the upstream IdP broker. No migration from a prior CAIPE-managed Keycloak is required for 0.4.18 upgraders. active_teamJWT claim: no data migration — the claim is simply no longer issued, and authorization is derived from channel context at request time.
Upgrade Runbook
1. Update chart version
helm upgrade ai-platform-engineering \
oci://ghcr.io/cnoe-io/charts/ai-platform-engineering \
--version 0.5.0 \
-f your-values.yaml
This alone is sufficient for a stock upgrade — the new authorization stack stays disabled.
2. Apply values.yaml changes
No breaking changes require edits. If you want to opt into RBAC, enable the foundation subcharts and point CAIPE UI at them:
tags:
keycloak: true
openfga:
enabled: true
caipe-ui:
config:
OPENFGA_HTTP: "http://ai-platform-engineering-openfga:8080"
OPENFGA_RECONCILE_ENABLED: "true"
KEYCLOAK_URL: "http://ai-platform-engineering-keycloak:8080"
To opt into the Webex bot:
tags:
webex-bot: true
To opt into the credential store (use aws-kms in production):
caipe-ui:
config:
CAIPE_CREDENTIALS_ENABLED: "true"
CREDENTIAL_KEY_PROVIDER: "aws-kms"
CREDENTIAL_KMS_CMK_ID: "<your-cmk-id>"
CREDENTIAL_KMS_REGION: "<your-region>"
For production secrets hygiene, consider turning on the new strict-mode gates once you have wired real secrets:
mongodb:
auth:
strictPasswords: true # fail-fast on placeholder rootPassword
3. Verify
kubectl get pods -n <namespace>
# If you enabled RBAC, confirm the auth foundation pods are healthy
kubectl get pods -n <namespace> | grep -E 'keycloak|openfga'
# If you enabled the Webex bot
kubectl get deploy -n <namespace> | grep webex-bot
For a stock upgrade, confirm all existing pods roll cleanly — no new admission constraints are introduced.
Full Values Diff
Raw diff (0.4.18 → 0.5.0)
--- /tmp/vf-0.5.0.yaml 2026-05-29 09:11:41
+++ /tmp/vt-0.5.0.yaml 2026-05-29 09:11:42
@@ -22,6 +22,8 @@
agent-petstore: false
rag-stack: false
slack-bot: false
+ webex-bot: false
+ keycloak: false
# Global configuration shared across all subcharts
global:
@@ -30,6 +32,11 @@
# Individual subchart `image.tag` values still take highest precedence.
image:
tag: ""
+ # -- Image repository channel for maintained CAIPE images.
+ # Empty means auto: rc/hotfix/dev chart appVersions use `pre-release/`,
+ # final release appVersions use the root published image repositories.
+ # Set to `pre-release` or `release` to force either repository channel.
+ channel: ""
# Deployment mode: "single-node" (all agents in-process) or "multi-node" (each agent as a separate pod)
deploymentMode: "multi-node"
@@ -115,7 +122,30 @@
agentgateway:
enabled: false
+ # Set to true only if Istio CRDs are NOT already present in the cluster.
+ # If Istio is already installed (any version), leave this false to avoid conflicts.
+ installIstioCrds: false
+ # Port for the agentgateway proxy listener (Gateway resource)
+ proxyPort: 8080
+ extAuth:
+ enabled: false
+ serviceName: "ai-platform-engineering-openfga-authz-bridge"
+ serviceNamespace: ""
+ port: 9100
+ # OpenFGA service discovery defaults for CAIPE components that perform
+ # relationship-based authorization or reconciliation.
+ openfga:
+ httpUrl: "http://{{ .Release.Name }}-openfga:8080"
+ storeName: "caipe-openfga"
+
+agentgateway:
+ enabled: false
+ image:
+ repository: cr.agentgateway.dev/agentgateway
+ tag: v1.1.0
+ pullPolicy: IfNotPresent
+
# LangGraph Redis for checkpoint and cross-thread store persistence.
# Two deployment options:
# 1. Dedicated Redis Stack (recommended): set enabled=true to deploy langgraph-redis subchart
@@ -276,6 +306,8 @@
USE_STRUCTURED_RESPONSE: "true" # Set to "true" to enforce agent to always use structured response format as the final output
TASK_CONFIG_PATH: "/app/task_config.yaml"
POLICY_FILE_PATH: "/app/policy.lp"
+ ENABLE_USER_INFO_TOOL: "false" # Capture user identity from JWT; enables user_info tool and JWT context middleware
+ FORWARD_JWT_TO_MCP: "false" # Forward the user JWT as Bearer token to HTTP/streamable-HTTP MCP connections (requires ENABLE_USER_INFO_TOOL=true). Also used by sub-agents via base_langgraph_agent.
# Self-service workflow env vars — referenced as ${VAR_NAME} in task_config.yaml prompts.
# Set these per environment so system workflows can resolve repo references at runtime.
# JARVIS_WORKFLOWS_REPO: "org/jarvis-workflows" # Templates repo (safe-settings, terraform, etc.)
@@ -377,6 +409,12 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ # Route MCP traffic through agentgateway proxy (requires global.agentgateway.enabled).
+ # When enabled, subagent MCP calls go through the agentgateway proxy which can
+ # enforce JWT validation and ext_authz decisions backed by OpenFGA.
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP # SSE or StreamableHTTP
agent-backstage:
nameOverride: "agent-backstage"
@@ -391,6 +429,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-confluence:
nameOverride: "agent-confluence"
@@ -404,6 +445,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
env:
TRANSPORT: "streamable-http"
@@ -478,6 +522,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-pagerduty:
nameOverride: "agent-pagerduty"
@@ -492,6 +539,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-slack:
nameOverride: "agent-slack"
@@ -505,6 +555,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 3001
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
command: ["--transport", "http"]
env:
SLACK_MCP_HOST: "0.0.0.0"
@@ -526,6 +579,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
env:
# -- Block kubectl get/describe secret(s) and redact Secret data from output. Defaults to true (on).
RESTRICT_KUBECTL_SECRETS: "true"
@@ -553,6 +609,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-victorops:
nameOverride: "agent-victorops"
@@ -566,6 +625,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-webex:
nameOverride: "agent-webex"
@@ -580,6 +642,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-weather:
nameOverride: "agent-weather"
@@ -608,6 +673,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-netutils:
nameOverride: "agent-netutils"
@@ -624,6 +692,9 @@
pullPolicy: "IfNotPresent"
mode: "http" # Options: stdio, http
port: 8000
+ agentgateway:
+ enabled: false
+ protocol: StreamableHTTP
agent-weather:
nameOverride: "agent-weather"
@@ -650,6 +721,25 @@
skills:
enabled: true
nameOverride: "caipe-ui"
+ # R1 upstream fix (May 2026): default the Keycloak Admin REST client
+ # secret name to "caipe-platform-secret" — the conventional name an
+ # operator passes via `keycloak.platformClient.secretRef` AND the
+ # default target of the keycloak chart's ExternalSecret (see below
+ # where we also default `keycloak.platformClient.secretRef` itself).
+ #
+ # Helm does not support cross-subchart value substitution at template
+ # time, so we have to hardcode the conventional name in both places.
+ # Operators using a non-default Secret name must override BOTH:
+ # keycloak.platformClient.secretRef: my-custom-platform-secret
+ # caipe-ui.keycloakAdminClient.secretName: my-custom-platform-secret
+ #
+ # See docs/docs/security/rbac/secrets-bootstrap.md section "R1: BFF
+ # Keycloak Admin token — production-safety gate".
+ # assisted-by Claude:claude-opus-4-7
+ keycloakAdminClient:
+ secretName: "caipe-platform-secret"
+ secretKey: "OIDC_CLIENT_SECRET"
+ clientId: "caipe-platform"
image:
repository: "ghcr.io/cnoe-io/caipe-ui"
# tag defaults to .Chart.AppVersion when not specified
@@ -719,6 +809,18 @@
DYNAMIC_AGENTS_ENABLED: "false"
# Dynamic Agents service URL (only used when DYNAMIC_AGENTS_ENABLED is "true")
# DYNAMIC_AGENTS_URL: "http://ai-platform-engineering-dynamic-agents:8001"
+ # Connections & Secrets credential store. Disabled by default. Use local-cmk
+ # only for non-production testing; production must use aws-kms.
+ CAIPE_CREDENTIALS_ENABLED: "false"
+ CREDENTIAL_STORE_BACKEND: "mongodb-envelope"
+ CREDENTIAL_KEY_PROVIDER: "local-cmk"
+ CREDENTIAL_KMS_CMK_ID: ""
+ CREDENTIAL_KMS_REGION: ""
+ CREDENTIAL_SERVICE_AUDIENCE: "caipe-credential-service"
+ # Bootstrap global OAuth connectors from server env at startup. In
+ # Kubernetes, provide provider client IDs/secrets/redirect URIs through
+ # externalSecrets; in Docker Compose, provide them through .env.
+ CREDENTIAL_BOOTSTRAP_OAUTH_CONNECTORS: "false"
# Standalone skill-scanner microservice (cisco-ai-defense/skill-scanner).
# Active when global.skillScanner.enabled=true; the in-cluster Service
# name is derived from the Helm release name, so the URL is rendered
@@ -729,6 +831,15 @@
SKILL_SCANNER_URL: "http://{{ .Release.Name }}-skill-scanner:8000"
# MongoDB configuration
MONGODB_DATABASE: "caipe"
+ # OpenFGA relationship authorization. Enable reconciliation only after
+ # OpenFGA is installed and the authorization model has been initialized.
+ OPENFGA_HTTP: ""
+ OPENFGA_STORE_NAME: "caipe-openfga"
+ OPENFGA_RECONCILE_ENABLED: "false"
+ # Keycloak Admin API integration for resource/scope synchronization.
+ KEYCLOAK_URL: ""
+ KEYCLOAK_REALM: "caipe"
+ KEYCLOAK_RESOURCE_SERVER_ID: "caipe-platform"
# NextAuth URL (non-sensitive)
NEXTAUTH_URL: "http://localhost:3000"
# Node environment
@@ -737,6 +848,29 @@
TAGLINE: "Multi-Agent Workflow Automation"
DESCRIPTION: "Where Humans and AI agents collaborate to deliver high quality outcomes."
APP_NAME: "CAIPE"
+ # Canonical Slack workspace namespace used by UI-managed Slack ReBAC/routes.
+ SLACK_WORKSPACE_ALIAS: "CAIPE"
+ # Slack bot internal admin API used by the Web UI BFF for route reload and
+ # one-time static-config-to-MongoDB/OpenFGA migration. The BFF uses the
+ # existing OIDC_CLIENT_ID/OIDC_CLIENT_SECRET Keycloak client credentials.
+ SLACK_BOT_ADMIN_URL: "http://ai-platform-engineering-slack-bot:3001"
+ SLACK_BOT_ADMIN_AUDIENCE: "caipe-slack-bot-admin"
+ # SLACK_BOT_ADMIN_TOKEN_URL: "http://keycloak:7080/realms/caipe/protocol/openid-connect/token"
+ # SLACK_BOT_ADMIN_SCOPE: "slack:routes:read slack:routes:reload slack:routes:sync"
+ SLACK_DEFAULT_TEAM_SLUG: ""
+ SLACK_DEFAULT_AGENT_ID: ""
+ # Webex bot internal admin API (BFF access-check + route management).
+ WEBEX_BOT_ADMIN_URL: "http://ai-platform-engineering-webex-bot:3002"
+ WEBEX_BOT_ADMIN_CLIENT_ID: "caipe-ui"
+ WEBEX_BOT_ADMIN_AUDIENCE: "caipe-webex-bot-admin"
+ # WEBEX_BOT_ADMIN_TOKEN_URL: "http://keycloak:7080/realms/caipe/protocol/openid-connect/token"
+ WEBEX_DEFAULT_TEAM_SLUG: ""
+ WEBEX_DEFAULT_AGENT_ID: ""
+ WEBEX_THREAD_CONTEXT_ENABLED: "true"
+ WEBEX_THREAD_CONTEXT_MAX_MESSAGES: "10"
+ WEBEX_THREAD_CONTEXT_MAX_CHARS: "4000"
+ CAIPE_ORG_KEY: "caipe"
+ CAIPE_ORG_DISPLAY_NAME: "CAIPE"
LOGO_URL: "/logo.svg"
LOGO_STYLE: "default"
# SPINNER_COLOR: ""
@@ -779,8 +913,18 @@
size: 10Gi
auth:
rootUsername: "admin"
- rootPassword: "changeme" # CHANGE THIS or use external secrets
+ # CHANGE THIS or use external secrets.
+ # R3 (May 2026): set `mongodb.strictPasswords: true` below to make
+ # `helm install` / `helm upgrade` fail-fast on the placeholder.
+ rootPassword: "changeme"
database: "caipe"
+ # R3: Production-safety gate. When true AND `externalSecrets.enabled`
+ # is false, the chart refuses to render if `auth.rootPassword` is a
+ # known placeholder ("changeme", "admin", "password", "mongo",
+ # "root", "test", etc.). Mirrors `keycloak.strictClientSecrets`.
+ # Default false so docker-compose dev + CI matrix keep working.
+ # assisted-by Claude:claude-opus-4-7
+ strictPasswords: false
# External Secrets for MongoDB credentials
externalSecrets:
enabled: false # Set to true to use external secrets
@@ -887,8 +1031,31 @@
port: 8001
# ConfigMap for non-sensitive configuration
config:
+ # ─── Keycloak / OIDC (REQUIRED for Bearer token validation) ─────────
+ # In-cluster Keycloak service URL used for the server-to-server JWKS
+ # fetch. The bundled Keycloak subchart exposes its service as
+ # `<release>-keycloak`; this default works for the umbrella chart
+ # but MUST be overridden when pointing dynamic-agents at an external
+ # Keycloak (production IdP / forge.dev / etc.).
+ KEYCLOAK_URL: "http://ai-platform-engineering-keycloak:8080"
+ # Browser-facing issuer string baked into JWTs (Keycloak's
+ # KC_HOSTNAME). Override when the public issuer differs from
+ # KEYCLOAK_URL (the typical production topology), e.g.
+ # OIDC_ISSUER: "https://idp.example.com/realms/caipe".
+ # Leaving this empty falls back to deriving the issuer from
+ # KEYCLOAK_URL, which only works in dev where both URLs coincide;
+ # NOTES.txt prints a warning otherwise.
+ OIDC_ISSUER: ""
# MongoDB configuration (uses same database as CAIPE UI)
MONGODB_DATABASE: "caipe"
+ # Connections & Secrets credential exchange client. Disabled by default.
+ CAIPE_CREDENTIALS_ENABLED: "false"
+ CREDENTIAL_API_URL: "http://ai-platform-engineering-caipe-ui:3000/api/credentials"
+ CREDENTIAL_SERVICE_AUDIENCE: "caipe-credential-service"
+ USE_IMPERSONATION_TOKENS: "false"
+ # MCP server IDs routed through the shared AgentGateway backend.
+ # Other MCP servers keep direct endpoints so tool names reflect real upstreams.
+ AGENT_GATEWAY_MCP_SERVER_IDS: "jira"
# LLM configuration (override if needed)
# LLM_PROVIDER: "openai"
# LLM_MODEL: "gpt-4o"
@@ -930,9 +1097,20 @@
SLACK_INTEGRATION_SILENCE_ENV: "false"
# MONGODB_URI: "" # Override per environment
# SLACK_WORKSPACE_URL: "" # e.g. "https://mycompany.slack.com"
+ SLACK_WORKSPACE_ALIAS: "CAIPE" # Canonical workspace namespace for Slack ReBAC/routes
# SLACK_INTEGRATION_ENABLE_AUTH: "true" # Enable OAuth2 Client Credentials
# OAUTH2_TOKEN_URL: "" # OIDC token endpoint
# OAUTH2_CLIENT_ID: "" # OAuth2 client ID
+ SLACK_AGENT_ROUTES_MODE: "db_prefer" # Prefer UI-managed Slack routes, fallback to static config
+ SLACK_AUTO_ASSIGN_UNMAPPED_CHANNELS: "false" # Opt-in first-message channel onboarding
+ SLACK_DEFAULT_TEAM_SLUG: "" # Required when auto-assignment is enabled
+ SLACK_DEFAULT_AGENT_ID: "" # Required when auto-assignment is enabled
+ SLACK_ADMIN_API_ENABLED: "false" # Internal admin API for route status/reload/config sync
+ SLACK_ADMIN_API_HOST: "0.0.0.0"
+ SLACK_ADMIN_API_PORT: "3001"
+ SLACK_ADMIN_JWT_ISSUER: "" # Set to Keycloak/OIDC issuer when admin API is enabled
+ SLACK_ADMIN_JWT_AUDIENCE: "caipe-slack-bot-admin"
+ SLACK_ADMIN_ALLOWED_CLIENT_IDS: "caipe-ui"
# -- Reference to a pre-existing Kubernetes Secret.
# Should contain: SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_SIGNING_SECRET,
@@ -963,10 +1141,41 @@
name: "vault"
kind: "ClusterSecretStore"
data: []
+ # Example placeholders. Keep values in your external secret backend; these
+ # keys are materialized into the generated Kubernetes Secret and injected
+ # into the slack-bot pod via envFrom.
# - secretKey: SLACK_BOT_TOKEN
# remoteRef:
# key: prod/slack-bot
# property: bot_token
+ # - secretKey: SLACK_APP_TOKEN
+ # remoteRef:
+ # key: prod/slack-bot
+ # property: app_token
+ # - secretKey: SLACK_SIGNING_SECRET
+ # remoteRef:
+ # key: prod/slack-bot
+ # property: signing_secret
+ # - secretKey: SLACK_CLIENT_SECRET
+ # remoteRef:
+ # key: prod/slack-bot
+ # property: slack_client_secret
+ # - secretKey: SLACK_LINK_HMAC_SECRET
+ # remoteRef:
+ # key: prod/slack-bot
+ # property: slack_link_hmac_secret
+ # - secretKey: OAUTH2_CLIENT_SECRET
+ # remoteRef:
+ # key: prod/slack-bot
+ # property: oauth2_client_secret
+ # - secretKey: KEYCLOAK_BOT_CLIENT_SECRET
+ # remoteRef:
+ # key: prod/slack-bot
+ # property: keycloak_bot_client_secret
+ # - secretKey: KEYCLOAK_SLACK_BOT_ADMIN_CLIENT_SECRET
+ # remoteRef:
+ # key: prod/slack-bot
+ # property: keycloak_slack_bot_admin_client_secret
resources:
requests:
@@ -976,6 +1185,215 @@
cpu: 500m
memory: 512Mi
+######### Webex Bot Integration configuration #########
+# Parallel to slack-bot: Webex spaces, identity linking, and OpenFGA ReBAC.
+# Enable with Helm tag: webex-bot=true
+webex-bot:
+ image:
+ repository: "ghcr.io/cnoe-io/caipe-webex-bot"
+ tag: ""
+ pullPolicy: "IfNotPresent"
+
+ config:
+ APP_NAME: "CAIPE"
+ CAIPE_API_URL: "http://ai-platform-engineering-caipe-ui:3000"
+ WEBEX_WORKSPACE_ALIAS: "CAIPE-WEBEX"
+ WEBEX_AGENT_ROUTES_MODE: "db_prefer"
+ WEBEX_THREAD_CONTEXT_ENABLED: "true"
+ WEBEX_THREAD_CONTEXT_MAX_MESSAGES: "10"
+ WEBEX_THREAD_CONTEXT_MAX_CHARS: "4000"
+ WEBEX_AUTO_ASSIGN_UNMAPPED_SPACES: "false"
+ WEBEX_DEFAULT_TEAM_SLUG: ""
+ WEBEX_DEFAULT_AGENT_ID: ""
+ WEBEX_ADMIN_API_ENABLED: "false"
+ WEBEX_ADMIN_API_HOST: "0.0.0.0"
+ WEBEX_ADMIN_API_PORT: "3002"
+ WEBEX_ADMIN_JWT_ISSUER: "http://ai-platform-engineering-keycloak:8080/realms/caipe"
+ WEBEX_ADMIN_JWKS_URL: "http://ai-platform-engineering-keycloak:8080/realms/caipe/protocol/openid-connect/certs"
+ WEBEX_ADMIN_JWT_AUDIENCE: "caipe-webex-bot-admin"
+ WEBEX_ADMIN_ALLOWED_CLIENT_IDS: "caipe-ui"
+ KEYCLOAK_URL: "http://ai-platform-engineering-keycloak:8080"
+ KEYCLOAK_REALM: "caipe"
+ OPENFGA_HTTP: "http://ai-platform-engineering-openfga:8080"
+ OPENFGA_STORE_NAME: "caipe-openfga"
+
+ # Wire OBO secret from Keycloak chart (see keycloak/templates/NOTES.txt).
+ keycloakBot:
+ clientSecretFromSecret:
+ name: "ai-platform-engineering-keycloak-webex-bot"
+ key: "KC_WEBEX_BOT_CLIENT_SECRET"
+
+ existingSecret: "webex-bot-secrets"
+
+ botConfig: {}
+
+ externalSecrets:
+ enabled: false
+ apiVersion: "v1beta1"
+ secretStoreRef:
+ name: "vault"
+ kind: "ClusterSecretStore"
+ data: []
+
+ resources:
+ requests:
+ cpu: 100m
+ memory: 256Mi
+ limits:
+ cpu: 500m
+ memory: 512Mi
+
+######### Keycloak Identity Provider configuration #########
+# Keycloak provides RBAC, identity federation (upstream SSO broker),
+# and token exchange (RFC 8693) for the Slack bot.
+# Enable with tag: keycloak=true
+keycloak:
+ image:
+ repository: "quay.io/keycloak/keycloak"
+ tag: "26.3"
+ pullPolicy: IfNotPresent
+
+ # Admin credentials — auto-generated random password by default.
+ # For prod: set admin.secretRef to an existing Secret, or enable
+ # externalSecrets to pull from Vault / AWS Secrets Manager.
+ admin:
+ username: admin
+ password: "" # Leave empty for auto-generated 32-char password
+ secretRef: "" # Set to an existing K8s Secret name with keys: username, password
+
+ realm:
+ name: caipe
+ sslRequired: "external" # "none" for dev, "external" for prod
+
+ # Keycloak features
+ features:
+ tokenExchange: true
+ adminFineGrainedAuthz: true
+
+ # Token exchange setup — enables bot impersonation via RFC 8693
+ tokenExchange:
+ enabled: true
+ botClientId: "caipe-slack-bot"
+ webexTokenExchange:
+ enabled: true
+ botClientId: "caipe-webex-bot"
+
+ # CAIPE platform OIDC client (the supervisor confidential client).
+ #
+ # R1 upstream fix (May 2026): the umbrella defaults `secretRef` to
+ # `caipe-platform-secret` so the keycloak chart's
+ # `platformClientSecretName` helper and the caipe-ui Deployment's
+ # `KEYCLOAK_ADMIN_CLIENT_SECRET` valueFrom.secretKeyRef both resolve
+ # to the same Secret name. An operator who:
+ # - pre-creates a K8s Secret called `caipe-platform-secret` with
+ # key `OIDC_CLIENT_SECRET`, OR
+ # - enables `externalSecret.enabled=true` (ESO emits a Secret of
+ # this same name as its target),
+ # gets the full BFF → Keycloak Admin REST wiring out of the box.
+ #
+ # Migration for existing ESO installs that used the OLD default name
+ # `<release>-keycloak-platform-client`: see
+ # docs/docs/security/rbac/secrets-bootstrap.md → R1 upstream fix.
+ # assisted-by Claude:claude-opus-4-7
+ platformClient:
+ secretRef: "caipe-platform-secret"
+
+ # Upstream IDP broker (generic OIDC — works with Okta, Azure AD, Duo, etc.)
+ # No vendor-specific credentials stored here.
+ idp:
+ enabled: false
+ alias: "" # e.g. "upstream-sso"
+ displayName: "" # e.g. "Enterprise SSO"
+ issuer: "" # OIDC issuer URL
+ clientId: ""
+ secretRef: "" # K8s Secret with key: IDP_CLIENT_SECRET
+ accessGroup: "" # Optional upstream group reference; mirrored into idp_groups only
+ adminGroup: "" # Optional upstream admin group reference; map to OpenFGA admin via Identity Group Sync
+
+ # External Secrets for admin password
+ externalSecrets:
+ enabled: false
+ apiVersion: "v1beta1"
+ secretStoreRef:
+ name: "vault"
+ kind: "ClusterSecretStore"
+ data: []
+ # - secretKey: password
+ # remoteRef:
+ # key: prod/keycloak
+ # property: admin_password
+
+ service:
+ type: ClusterIP
+ port: 8080
+
+ resources:
+ requests:
+ cpu: 250m
+ memory: 512Mi
+ limits:
+ cpu: "1"
+ memory: 1Gi
+
+######### OpenFGA Relationship PDP configuration #########
+# OpenFGA stores team/resource tuples used by the UI and the AgentGateway
+# ext_authz bridge. Enable for RBAC/ReBAC installs.
+openfga:
+ enabled: false
+ image:
+ repository: openfga/openfga
+ tag: v1.15.1
+ pullPolicy: IfNotPresent
+ init:
+ enabled: true
+ storeName: caipe-openfga
+ seedTuples: []
+ datastore:
+ engine: memory
+ uriSecretRef:
+ name: ""
+ key: OPENFGA_DATASTORE_URI
+ migrate:
+ enabled: true
+
+######### OpenFGA AgentGateway ext_authz bridge #########
+# The bridge receives Envoy ext_authz checks from AgentGateway and performs
+# OpenFGA Check calls. Enable alongside OpenFGA and AgentGateway.
+openfgaAuthzBridge:
+ enabled: false
+
+# Values for the openfga-authz-bridge subchart. The separate camelCase block
+# above is kept as the dependency condition flag.
+openfga-authz-bridge:
+ image:
+ repository: ghcr.io/cnoe-io/openfga-authz-bridge
+ tag: ""
+ pullPolicy: IfNotPresent
+ openfga:
+ httpUrl: "http://{{ .Release.Name }}-openfga:8080"
+ storeName: caipe-openfga
+ relation: can_call
+ object: mcp_gateway:list
+ agentContext:
+ existingSecret:
+ name: ""
+ key: CAIPE_AGENT_CONTEXT_HMAC_SECRET
+ tokenValidation:
+ jwksUrl: "http://{{ .Release.Name }}-keycloak:8080/realms/caipe/protocol/openid-connect/certs"
+ issuer: ""
+ audiences: []
+ algorithms:
+ - RS256
+ audit:
+ enabled: true
+ mongodbUri: ""
+ mongodbDatabase: caipe
+ tenantId: default
+ subjectSalt: caipe-098-audit
+ existingSecret:
+ name: ""
+ key: MONGODB_URI
+
######### RAG Stack configuration #########
# RAG Stack - Complete stack including web, server, agent, Redis, and Milvus
# Below values are only a subset of the values that are available in the rag-stack chart.
