feat(rbac): org-level ingest/search capabilities + FGA coverage guarantee#1716
Conversation
|
✅ No proprietary content detected. This PR is clear for review! |
🧪 CAIPE UI Test Results✅ All tests passed 🟠 Overall Coverage: 55%📊 Detailed Coverage
✅ Test Suites
📈 Coverage Thresholds
|
The merge-base changed after approval.
…enforcement Introduce explicit, org-scoped `ingestor`/`can_ingest` and `searcher`/`can_search` relations in the OpenFGA model (authored .fga + deployed chart JSON) and enforce them in the RAG server. Datasource create/ingest paths now require `can_ingest` and search/MCP-invoke paths require `can_search`, both opt-in by default so a generic user gets neither until an admin grants their team the capability. Also adds the `anonymous` subject-only type to the authored model for parity with the deployed chart JSON. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Add an admin toggle (BFF routes + IngestCapabilityToggle) to opt a team into the org-level can_ingest capability, the ingest-teams listing API, and gate the IngestView UI so non-capable users cannot reach ingest controls. Includes the spec doc and the org-ingest-capability ReBAC contract test. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…ting Add an admin toggle (BFF routes + SearchCapabilityToggle, surfaced in TeamDetailsDialog) to opt a team into the org-level can_search capability, and enforce it on the search/MCP-invoke proxy and the KB sidebar tab gates. The kb-tab-gates route and useRagPermissions/use-kb-tab-gates hooks now fail closed so users without can_search no longer see or query default/caipe_kb. Includes the spec doc and the org-search-capability ReBAC contract test. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Add ReBAC contract and authorization-matrix tests for custom MCP tool can_call, org-wide and team-invoke sharing, ownership transfer, and data_source/mcp_tool parent_kb inheritance, plus RAG server MCP tool endpoint tests. Updates the unified shareable-resource spec with a test-coverage map and db-migration notes. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
… guards Add a four-layer, CI-enforced invariant so no resource type can land ungated (spec 2026-06-04-fga-coverage-guarantee): - Layer 1 type parity: derive UniversalRebacResourceType from a runtime const array and assert the object-type set agrees across model.fga, the chart JSON, the TS union, and the registry (minus a subject-only allowlist). Registers the previously-unregistered data_source and mcp_tool types. - Layer 2 enforcement manifest: classify every type (rebac_enforced/role_gated/ rebac_shadowed/not_gated) with on-disk surfaces; reject unclassified types. - Layer 3 create-path linter: validate-fga-create-paths.py (wired into make test-rbac-lint) asserts each ownable type ownership-write helper is defined and called from production code. - Layer 4 default-deny backstop: parametrized test proving a tuple-less subject is denied read/use/manage on every type and that the unsafe bypass is off. Updates the RBAC living docs (architecture.md, file-map.md). Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…ntials Prevent UI restarts from wiping discovered MCP servers by self-healing them during seed-config reconciliation, and backfill missing MCP credential sources from Mongo. Adds agentgateway MCP discovery handling and the dynamic-agents Mongo credential-source self-heal path, with covering tests. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Add scripts/debug-container.sh to attach a debugging shell/toolset to running distroless containers at runtime without baking tools into the image. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
- Remove the unused `act` import from TeamOwnershipFields.test.tsx (genuine unused-symbol finding). - Keep the two FastAPI dependency-override lambdas in test_mcp_tool_endpoints.py but document why: the bot flagged them as unnecessary wrappers, but a bare `_user` (which has role/subject default params) or bare `object` builtin would be introspected by FastAPI and turn those params into request query params. The lambda intentionally hides the signature so the override is called with zero args. Suggestion declined with rationale. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
The merge-base changed after approval.
bcb6cc3 to
962f7ea
Compare
| # NOTE: keep the lambda — a bare `_user` would expose its (role, subject) | ||
| # default params to FastAPI as query parameters. The lambda hides the | ||
| # signature so the override is always called with zero args. | ||
| restapi.app.dependency_overrides[require_authenticated_user] = lambda: _user() |
| restapi.app.dependency_overrides.pop(require_authenticated_user, None) | ||
| # NOTE: keep the lambda — passing the bare `object` builtin makes FastAPI | ||
| # attempt signature introspection on it; the lambda yields a plain stub. | ||
| restapi.app.dependency_overrides[get_auth_manager] = lambda: object() |
Prebuild Artifacts for `bbfeb4a` (archived)Prebuild Artifacts for
|
| Artifact | Image | Tag | Status | CI |
|---|---|---|---|---|
| caipe-dynamic-agents | ghcr.io/cnoe-io/prebuild/caipe-dynamic-agents |
feat-rbac-org-capabilities-and-fga-coverage-10 |
Published | CI |
| caipe-rag-agent-ontology | ghcr.io/cnoe-io/prebuild/caipe-rag-agent-ontology |
feat-rbac-org-capabilities-and-fga-coverage-10 |
Published | CI |
| caipe-rag-ingestors | ghcr.io/cnoe-io/prebuild/caipe-rag-ingestors |
feat-rbac-org-capabilities-and-fga-coverage-10 |
Published | CI |
| caipe-rag-server | ghcr.io/cnoe-io/prebuild/caipe-rag-server |
feat-rbac-org-capabilities-and-fga-coverage-10 |
Published | CI |
| caipe-ui | ghcr.io/cnoe-io/prebuild/caipe-ui |
feat-rbac-org-capabilities-and-fga-coverage-10 |
Published | CI |
Docker pull commands
docker pull ghcr.io/cnoe-io/prebuild/caipe-dynamic-agents:feat-rbac-org-capabilities-and-fga-coverage-10
docker pull ghcr.io/cnoe-io/prebuild/caipe-rag-agent-ontology:feat-rbac-org-capabilities-and-fga-coverage-10
docker pull ghcr.io/cnoe-io/prebuild/caipe-rag-ingestors:feat-rbac-org-capabilities-and-fga-coverage-10
docker pull ghcr.io/cnoe-io/prebuild/caipe-rag-server:feat-rbac-org-capabilities-and-fga-coverage-10
docker pull ghcr.io/cnoe-io/prebuild/caipe-ui:feat-rbac-org-capabilities-and-fga-coverage-10Helm Charts
| Chart | Registry | Version | Status | CI |
|---|---|---|---|---|
| ai-platform-engineering | ghcr.io/cnoe-io/prebuild-helm-charts |
0.5.7-dev.13-feat-rbac-org-capabilities-and-fga-coverage-9 |
Published | CI |
Helm install commands
helm upgrade --install ai-platform oci://ghcr.io/cnoe-io/prebuild-helm-charts/ai-platform-engineering --version 0.5.7-dev.13-feat-rbac-org-capabilities-and-fga-coverage-9These prebuild artifacts will be automatically cleaned up when the PR is closed or merged.
The new requireSearchCapability gate (spec 2026-06-03) runs as the OUTER gate on /v1/mcp/invoke, before the per-tool can_call / custom-tools-listing logic. The #1710 fails-CLOSED-503 test denied every FGA tuple, so it tripped the can_search gate (403) before reaching the listing-error fail-closed path it intends to verify. Grant the caller the org can_search capability so we pass the outer gate and still exercise the 503 fail-closed behaviour (deny-all would have dropped that coverage entirely). Both invariants remain covered: no can_search -> 403, and can_search + listing error -> 503 with no forward. Test-only change. Assisted-by: Cursor claude-opus-4.8 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com> Co-authored-by: Cursor <cursoragent@cursor.com>
ℹ️ Branch is behind
|
Prebuild Artifacts for
|
| Artifact | Image | Tag | Status | CI |
|---|---|---|---|---|
| caipe-dynamic-agents | ghcr.io/cnoe-io/prebuild/caipe-dynamic-agents |
feat-rbac-org-capabilities-and-fga-coverage-12 |
Published | CI |
| caipe-rag-agent-ontology | - | - | Failed | CI |
| caipe-rag-ingestors | ghcr.io/cnoe-io/prebuild/caipe-rag-ingestors |
feat-rbac-org-capabilities-and-fga-coverage-12 |
Published | CI |
| caipe-rag-server | - | - | Failed | CI |
| caipe-ui | ghcr.io/cnoe-io/prebuild/caipe-ui |
feat-rbac-org-capabilities-and-fga-coverage-12 |
Published | CI |
Docker pull commands
docker pull ghcr.io/cnoe-io/prebuild/caipe-dynamic-agents:feat-rbac-org-capabilities-and-fga-coverage-12
docker pull ghcr.io/cnoe-io/prebuild/caipe-rag-ingestors:feat-rbac-org-capabilities-and-fga-coverage-12
docker pull ghcr.io/cnoe-io/prebuild/caipe-ui:feat-rbac-org-capabilities-and-fga-coverage-12Helm Charts
| Chart | Registry | Version | Status | CI |
|---|---|---|---|---|
| ai-platform-engineering | ghcr.io/cnoe-io/prebuild-helm-charts |
0.5.7-dev.13-feat-rbac-org-capabilities-and-fga-coverage-10 |
Published | CI |
Helm install commands
helm upgrade --install ai-platform oci://ghcr.io/cnoe-io/prebuild-helm-charts/ai-platform-engineering --version 0.5.7-dev.13-feat-rbac-org-capabilities-and-fga-coverage-10These prebuild artifacts will be automatically cleaned up when the PR is closed or merged.
Summary
Builds on #1711 (custom MCP tool OpenFGA authz). Adds explicit, opt-in org-level
capabilities so a generic user gets nothing until an admin grants their team, plus
a build-time invariant that every resource type stays FGA-gated.
ingestor/can_ingestrelations + RAGserver enforcement, admin toggle, ingest-teams API, and ingest UI gating.
searcher/can_searchrelations enforcedon search/MCP-invoke and KB tab gates (fixes generic users seeing/searching
default/caipe_kbafter un-share), admin toggle in TeamDetailsDialog.parity, enforcement manifest, create-path ownership linter, default-deny
backstop) so no new resource type can land ungated. Registers
data_source/mcp_tool; adds the subject-onlyanonymoustype for chart parity.transfer, and
parent_kbinheritance contract/matrix coverage.backfills missing MCP credential sources from Mongo.
scripts/debug-container.shfor runtime debugging ofdistroless containers.
Test plan
make test-rbac-lint(incl. FGA create-path + matrix linters)cd ui && npx jest(rbac/ rag-rbac/ seed-config/ capability suites)PYTHONPATH=. uv run pytest tests/test_validate_fga_create_paths.pytoggles flip access; un-sharing caipe_kb revokes search
Assisted-by: Cursor claude-opus-4.8
Made with Cursor