Problem Statement: Centralized BFF Authorization & PDP-Agnostic API
Status: Draft for second-opinion review
Date: 2026-06-05
Authors: Sri Aradhyula (problem framing); AI-assisted synthesis from PR review + team discussion
Audience: Platform engineers, security architects, agents reviewing implementation options
Related work:
| Link | Role |
|---|---|
| PR #1751 | Workflow RBAC visibility, run access, unsaved UX, agent-access modal |
| PR #1751 review r3362688683 | @subbaksh: workflows are UI/BFF concept; DA should not own workflow RBAC |
| Issue #1742 | Epic: RBAC/Auth review remediation (PR #1444 follow-ups) |
| Issue #1755 | Skills RBAC UI parity / shared-module hygiene (#1727 follow-up) |
| Issue #1455 | Runtime BFF ReBAC endpoints for Slack/Webex bots |
| Issue #1454 | Refactor DA runtime auth surface |
| Issue #1731 | Duplicate OpenFGA can_use on DA chat path |
| Issue #1734β#1738 | RAG thin PEP / Mongo in hot path |
1. Executive summaryβ
CAIPE has reusable RBAC modules on the BFF (Next.js UI server) and CI guards for new resource types, but authorization is still implemented inconsistently across surfaces:
- Dynamic Agents (DA) sometimes reads MongoDB for UI-domain data (e.g.
workflow_configs,teams) and duplicates OpenFGA checks the BFF already performs. - RAG still uses a monolithic
server/rbac.pythat mixes token validation, legacy roles, OpenFGA, and MongoDB β a different pattern than agents/KB/MCP on the BFF. - Public APIs and errors expose OpenFGA-specific concepts (
agent#use,pdp_denied, tuple strings), coupling integrators and UI copy to the current PDP. - HTTP authorization is fragmented: admin-only
rebac/check, domain-specificaccess-checkroutes, and no generic runtime evaluate API for service callers (bots, DA).
After testing 0.5.9 and reviewing PR #1751, the team wants to:
- Stop creating anti-patterns (DA β Mongo for workflows; one-off RBAC per resource).
- Enforce shared module usage going forward (linters, hygiene).
- Make the authorization API PDP-agnostic so OpenFGA is an implementation detail, not a user-facing contract.
- Centralize policy decisions on the BFF where platform domain data lives (workflows, teams, visibility).
This document captures the problem statement, current state, stakeholder input, and implementation options for a follow-up spec.
2. Problem statementβ
2.1 Core problemβ
Authorization logic and platform domain data are scattered across BFF, Dynamic Agents, RAG, and Slack bot, with multiple parallel patterns for the same decision (user X may use resource Y). This causes:
- Architectural drift β reviewers repeatedly flag DA/RAG reading Mongo or re-implementing visibility rules that belong on the BFF.
- Duplicate PDP hops β BFF checks OpenFGA, then DA checks OpenFGA again (latency, availability, confusion about source of truth).
- Inconsistent developer experience β agents use
shareable-resource.ts+resource-authz.ts; RAG usesrbac.py; workflows added DA-side Mongo reads in PR #1751. - Leaky abstraction β API consumers see OpenFGA relation names and PDP jargon instead of stable product-level denial reasons.
- Weak enforcement β CI guarantees new types are registered and default-deny tested, but does not force routes/services to use shared modules vs ad-hoc checks.
2.2 Triggering incidents (this conversation)β
A. PR #1751 β workflow RBAC + DA delegationβ
PR #1751 adds:
- BFF: workflow visibility, run access gates, team slug normalization, unsaved UX, agent-access modal on save.
- DA:
workflow_execution_authz.pyβ readsworkflow_configsandteamsfrom Mongo; allowsagent#can_usebypass whenworkflow_config_idis passed on chat requests.
Reviewer feedback (@subbaksh, r3362688683):
Workflows are purely a UI server concept. The UI invokes agents one step at a time. DA usually has no clue whether it's a workflow or a user chatting. For invocation β the DA server just has a tool (with
workflow_idparam) that it calls to invoke a workflow. The RBAC for invocation should be in UI server no?
Assessment: The reviewer is aligned with epic #1742. Workflow lifecycle auth already exists on the BFF (/api/workflow-runs, workflow-config-rebac.ts). DA Mongo reads are an anti-pattern; the bypass exists only because the workflow engine forwards the user JWT to DA and DA enforces agent#can_use independently.
B. Reusable modules β one path did not use themβ
Shared modules were introduced for unified shareable resource RBAC (spec 2026-06-03-unified-shareable-resource-rbac):
- Write path:
ui/src/lib/rbac/shareable-resource.tsβopenfga-owned-resources.ts(reconcileShareableResource) - Read path:
ui/src/lib/rbac/resource-authz.ts(requireResourcePermission,filterResourcesByPermission)
Skills team sharing was fixed in #1729 to use reconcileShareableResource. Follow-up #1755 tracks optional UI DRY (useShareableTeams hook) and documents explicit non-goals (skills as owner-team resources).
Gap: Not every feature path uses the shared stack. PR #1751βs DA workflow auth is the latest example of bypassing BFF modules entirely.
C. Team discussion (Kevin Kantesaria, 2026-06-05)β
Paraphrased Slack thread:
| Speaker | Point |
|---|---|
| Sri | Created #1755 to track cleanup after reusable modules; one instance did not use them. |
| Kevin | Push cleanup soon so we donβt keep creating anti-patterns; unsure how to enforce going forward. |
| Sri | Added basic RBAC enforcement for new resources; need linters and hygiene. |
| Kevin | Does that enforcement use the modules? Original problem: RAG and agents used different RBAC setups β want to avoid that. |
| Kevin / Sri | Make OpenFGA less obvious to end users; API should be agnostic if we switch PDP. |
2.3 Goals (desired end state)β
- Single policy ownership β BFF owns platform domain data (workflows, teams, visibility) and composes FGA + product rules.
- Single module stack β application code uses
shareable-resource/resource-authz(or a thin facade), not rawopenfga.tsor service-local Mongo policy. - PDP-agnostic public contract β HTTP and user-facing errors use
{ resource, action, reason }, notcan_use/agent#use/pdp_denied. - Thin PEPs downstream β DA, RAG, bots either trust BFF decisions via API or verify signed claims; they do not read
workflow_configsfrom Mongo for authz. - Enforceable in CI β import boundaries, create-path linter extensions, no new anti-patterns without explicit spec exception.
2.4 Non-goals (for initial spec)β
- Replacing OpenFGA as the relationship store (unless a separate strategic decision).
- Removing all OpenFGA checks from DA in v1 (tracked as #1731; depends on #1458 dual-gate documentation).
- Migrating skills to owner-team model (#1708) β separate from this problem.
3. Current state (as of 2026-06-05, branch prebuild/feat/workflow-rbac-visibility-unsaved)β
3.1 BFF authorization layersβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BFF route handler (ui/src/app/api/**/route.ts) β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββΌββββββββββββββββββββ
βΌ βΌ βΌ
requireRbacPermission requireResourcePermission Domain helpers
(api-middleware.ts) (resource-authz.ts) (workflow-config-rebac,
org/capability gates slack-channel-rebac, β¦)
β β β
βββββββββββββββββββββΌββββββββββββββββββββ
βΌ
checkOpenFgaTuple / checkUniversalRebacRelationship
(openfga.ts)
βΌ
OpenFGA HTTP API
Key modulesβ
| Module | Path | Responsibility |
|---|---|---|
| OpenFGA transport | ui/src/lib/rbac/openfga.ts | checkOpenFgaTuple, tuple read/write/reconcile |
| Resource ReBAC | ui/src/lib/rbac/resource-authz.ts | requireResourcePermission, filterResourcesByPermission, requireAgentPermission, requireSkillPermission |
| Agent use (chat proxy) | ui/src/lib/rbac/openfga-agent-authz.ts | requireAgentUsePermission β used by /api/v1/chat/* |
| Agent use (audit path) | ui/src/lib/rbac/pdp-shared.ts | evaluateAgentAccess β direct + team-union with reason codes |
| Shareable write | ui/src/lib/rbac/shareable-resource.ts | handleShareableResourceWrite, resolveShareableOwnershipWrite |
| FGA reconcile | ui/src/lib/rbac/openfga-owned-resources.ts | reconcileShareableResource |
| Workflow policy | ui/src/lib/rbac/workflow-config-rebac.ts | Visibility, workflowDelegatesAgentUse, reconcileWorkflowConfigAccess (uses reconcileShareableResource) |
| Access explain (admin) | ui/src/lib/rbac/access-explainer.ts | explainAccess + Mongo provenance |
| Type registry | ui/src/types/rbac-universal.ts | UniversalRebacResourceType, UniversalRebacRelationship |
| Enforcement manifest | ui/src/lib/rbac/fga-enforcement-manifest.ts | Per-type rebac_enforced / surfaces for auditors |
HTTP APIs that expose authorization todayβ
| Endpoint | Auth gate | Purpose | Runtime-safe? |
|---|---|---|---|
POST /api/admin/rebac/check | admin_ui#view | Explain access (explainAccess) | No β admin only |
POST /api/integrations/slack/.../access-check | Session + slack_channel#read | checkSlackChannelAccess | Partial β bot path evolving |
POST /api/integrations/webex/.../access-check | Same pattern | Webex space access | Partial |
POST /api/admin/slack/.../access-check | Admin | Diagnostics | No |
POST /api/admin/openfga/relationship | Admin | Tuple grant/revoke | No (write) |
POST /api/workflow-runs | assertCanExecuteWorkflowRunsForConfigId | Start run | Yes β domain API |
POST /api/workflow-configs/check-agent-access | withAuth | Pre-save agent gap check (PR #1751) | Yes β BFF-only |
DA WorkflowApiClient β /api/workflow-runs | OAuth2 client credentials | Workflow tools from agents | Yes β correct pattern |
There is no generic POST /api/runtime/authorize today.
Spec draft exists: docs/docs/specs/2026-05-11-identity-group-rebac/contracts/rebac-policy-api.md (POST /api/admin/rebac/check with UniversalRebacRelationship).
3.2 CI enforcement (FGA coverage guarantee, spec 2026-06-04)β
| Layer | Artifact | What it enforces |
|---|---|---|
| 1 | fga-type-coverage.test.ts | OpenFGA model β‘ type registry β‘ chart |
| 2 | fga-enforcement-manifest.test.ts | Every type classified; enforced surfaces exist on disk |
| 3 | scripts/validate-fga-create-paths.py | Ownable types wire reconcile*Relationships from production routes |
| 4 | default-deny-coverage.test.ts | New types auto-covered for deny-by-default |
Gap: Layers 1β4 do not require routes to call shareable-resource / resource-authz vs ad-hoc checkOpenFgaTuple. They do not block DA/RAG Mongo reads for authz.
3.3 Dynamic Agents β workflow-related anti-patternsβ
| Location | Mongo / policy | Issue |
|---|---|---|
dynamic_agents/auth/workflow_execution_authz.py | Reads workflow_configs, teams | Duplicates BFF visibility; reviewer rejected |
dynamic_agents/auth/openfga_authz.py | OpenFGA + workflow bypass | Third auth layer on chat path |
dynamic_agents/services/agent_runtime.py | Reads workflow_configs for builtin tool validation | Should use BFF resolve API |
dynamic_agents/services/builtin_tools.py | WorkflowApiClient β BFF | Correct pattern for invocation |
3.4 RAG vs agents β divergent stacksβ
| Concern | Agents / BFF resources | RAG server |
|---|---|---|
| Read/use gate | resource-authz.ts β OpenFGA | server/rbac.py (mixed) |
| Share/write | shareable-resource.ts | Partial (KB sharing route on BFF); ingestor paths differ |
| Mongo in authz hot path | Mostly moved to BFF | Still present (#1736) |
| Target architecture | Unified shareable resource RBAC | Thin PEP plan |
Kevinβs concern: βRAG and agents used different RBAC setupsβ β still true at the Python RAG layer.
3.5 PR #1751 commit inventory (relevant)β
| Commit / area | BFF-aligned? | Notes |
|---|---|---|
Workflow run access (workflow-run-access.ts) | Yes | |
workflow-config-rebac.ts + reconcileShareableResource | Yes | |
Unsaved UX, team slugs, TeamMultiPicker | Yes | |
check-agent-access + WorkflowAgentAccessModal | Yes | Pre-grant agent tuples on save |
workflow_execution_authz.py on DA | No | Remove or defer to epic |
workflow_config_id on DA chat body | No | Remove with above |
3.6 User-visible OpenFGA leakage (examples)β
From openfga-agent-authz.ts and resource-authz.ts:
{
"success": false,
"error": "Permission denied",
"code": "agent#use",
"reason": "pdp_denied",
"action": "contact_admin"
}
Admin explain responses include FGA tuple strings. Audit events use pdp: "openfga". These are appropriate for operators, not for generic API consumers or end-user copy.
4. Architectural principles (agreed direction)β
- Workflows are a BFF concern β config, visibility, run orchestration, delegation checks live in UI server +
workflow-engine.ts. - DA invokes agents; DA workflow tools invoke workflows via BFF β
WorkflowApiClientis the model. - OpenFGA is the current PDP for relationships β but callers should not depend on FGA tuple shape.
- Defense-in-depth is optional and explicit β duplicate DA OpenFGA (#1731) must be a documented choice (#1458), not accidental duplication.
- Epic #1742 phases β runtime BFF endpoints (#1455) before bots/DA drop Mongo.
5. Options (detailed)β
Option 1 β In-process Authz facade (BFF library)β
Summary: Introduce ui/src/lib/authz/ as the only import surface for application authorization. OpenFGA moves behind a PolicyEngine interface.
Proposed structureβ
ui/src/lib/authz/
index.ts # authorize(), filterAccessible(), reconcileShares()
types.ts # Subject, Resource, Action, Decision (PDP-agnostic)
errors.ts # PERMISSION_DENIED, AUTHZ_UNAVAILABLE
engines/
openfga-adapter.ts # implements PolicyEngine today
domains/
workflow.ts # workflowDelegatesAgentUse, visibility (Mongo product policy)
slack-channel.ts
webex-space.ts
Public API (sketch)β
interface AuthorizeRequest {
subject: { type: "user" | "service_account"; id: string };
resource: { type: UniversalRebacResourceType; id: string };
action: ResourcePermissionAction;
context?: Record<string, unknown>; // workflow_id, channel_id, etc.
}
interface AuthorizeDecision {
allowed: boolean;
reason: "OK" | "NO_CAPABILITY" | "AUTHZ_UNAVAILABLE" | "INVALID_REQUEST";
action?: "sign_in" | "contact_admin" | "retry";
// Admin-only extension:
debug?: { engine: string; path?: string };
}
async function authorize(req: AuthorizeRequest): Promise<AuthorizeDecision>;
async function authorizeOrThrow(req: AuthorizeRequest): Promise<void>;
Migrationβ
- Wrap existing
resource-authz.ts,pdp-shared.ts, domain modules. - Deprecate direct
checkOpenFgaTupleimports outsidelib/authz/**. - Map existing
ApiErrorcodes to PDP-agnostic envelope.
Prosβ
- No new network hop; fits existing Next.js deployment.
- Clear import boundary for ESLint.
- Enables future non-OpenFGA engine without route changes.
Consβ
- Does not alone fix DA/RAG β they donβt run inside BFF.
- Requires disciplined migration of ~dozens of route call sites.
Enforcementβ
// eslint no-restricted-imports
"@/lib/rbac/openfga" β only from "@/lib/authz/**"
Option 2 β Runtime HTTP authorize API (BFF routes)β
Summary: Expose authorization decisions as HTTP for service callers (Slack bot, Webex bot, Dynamic Agents). Implements #1455 and generalizes access-check routes.
Proposed endpointβ
POST /api/runtime/authorize
Authorization: Bearer <user-jwt | service-account-token>
Content-Type: application/json
{
"subject": { "type": "user", "id": "<oidc-sub>" },
"resource": { "type": "agent", "id": "platform-engineer" },
"action": "use",
"context": {
"workflow_config_id": "wf-optional-hint"
}
}
Response (allow):
{
"allowed": true,
"reason": "OK"
}
Response (deny):
{
"allowed": false,
"reason": "NO_CAPABILITY",
"action": "contact_admin"
}
Response (PDP down):
{
"allowed": false,
"reason": "AUTHZ_UNAVAILABLE",
"action": "retry"
}
Domain-specific endpoints (alternative/complement)β
Instead of one generic endpoint, extend the access-check pattern:
| Endpoint | Caller | Checks |
|---|---|---|
POST /api/runtime/authorize | Generic | FGA + optional context handlers |
POST /api/runtime/workflows/authorize-run | DA, internal | Workflow visibility + step agents |
POST /api/runtime/workflows/resolve-configs | DA | Replace Mongo workflow_configs read |
Existing Slack/Webex access-check | Bots | Channel/space scoped |
Authentication modelβ
- User bearer β subject must match token
sub(or OBO chain). - Service account β
service_account:<client_id>in FGA; may evaluate on behalf of user whencontext.delegated_subjectis present and bot OBO is valid (needs threat model).
Prosβ
- DA/RAG/bots stop reading Mongo for policy.
- Single HTTP contract for integrators.
- Aligns with epic #1742 prerequisite #1455.
Consβ
- Latency and availability β every DA chat could add BFF round-trip unless cached or combined with Option 3.
- Duplicates #1731 debate if DA still checks OpenFGA after BFF says allow.
Implementation notesβ
- Implement handlers by delegating to Option 1 facade internally.
- Admin
POST /api/admin/rebac/checkremains explain-only with richerdebugpayload.
Option 3 β Signed authorization claims (PEP-only downstream)β
Summary: BFF is the sole PDP. After authorize(), BFF mints a short-lived signed claim (JWT or HMAC macaroon) attached to downstream requests. DA/RAG verify signature + expiry only.
Claim sketchβ
{
"iss": "caipe-bff",
"sub": "user:<oidc-sub>",
"resource": "agent:platform-engineer",
"action": "use",
"iat": 1710000000,
"exp": 1710000060,
"jti": "unique-id"
}
DA require_agent_use_permission becomes require_authorization_claim β no OpenFGA client in DA.
Prosβ
- Eliminates duplicate OpenFGA in DA (#1731).
- True PDP agnostic at service boundary.
- Workflow delegation encoded in claim issuance on BFF (no
workflow_config_idon DA).
Consβ
- Largest engineering cost: key management, revocation, clock skew, claim replay.
- Requires #1458 dual-gate retirement plan.
- Workflow engine currently forwards user JWT β would need claim issuance at run start and per step.
When to chooseβ
- Phase 3+ of #1742, after runtime BFF API proves correct.
Option 4 β Enforcement-first (linters + manifest, minimal API change)β
Summary: Keep current modules; block anti-patterns in CI without redesigning HTTP APIs yet.
Proposed guardsβ
| Guard | Mechanism | Blocks |
|---|---|---|
| Import boundary | ESLint no-restricted-imports | checkOpenFgaTuple outside lib/rbac/** or lib/authz/** |
| Service boundary | scripts/validate-authz-boundaries.py | workflow_configs / teams reads in dynamic_agents/** for authz |
| Route coverage | Extend validate-fga-create-paths.py or new script | New routes must import from resource-authz or authz facade |
| Manifest update | fga-enforcement-manifest.ts | Add surfaces for task (workflows), runtime authorize routes |
| PR template | Checkbox | βUses shareable-resource / resource-authz / domain wrapperβ |
Prosβ
- Fastest win; addresses Kevinβs βdonβt create more anti-patterns.β
- Low risk; parallel to other options.
Consβ
- Does not fix RAG
rbac.pyor user-visible OpenFGA strings. - Does not give DA a supported API without Option 2.
Option 5 β Universal relationship contract (spec-only standardization)β
Summary: Standardize all checks on UniversalRebacRelationship from rbac-universal.ts β already in rebac-policy-api.md.
Request shapeβ
{
"subject": { "type": "user", "id": "user-123", "relation": "member" },
"action": "use",
"resource": { "type": "agent", "id": "platform-engineer" },
"context": { "slack_channel": "C123" }
}
Mappingβ
- Internal:
checkUniversalRebacRelationship(relationship)inopenfga.ts. action: "use"maps to FGA relationcan_useinside adapter β not exposed to clients.
Prosβ
- One vocabulary for docs, admin UI, runtime API, tests.
- Natural fit for Option 1 + Option 2.
Consβ
actionnames still mirror current FGA model; true PDP swap requires adapter mapping table per engine.
6. PDP-agnostic public surface (cross-cutting)β
Regardless of option, define a stable external contract:
6.1 Error envelope migrationβ
| Current | Target (public) | Admin/debug only |
|---|---|---|
code: "agent#use" | code: "PERMISSION_DENIED" | detail: "agent#use" |
reason: "pdp_denied" | reason: "NO_CAPABILITY" | |
reason: "pdp_unavailable" | reason: "AUTHZ_UNAVAILABLE" | |
pdp: "openfga" in JSON body | Omit | Keep in audit logs |
| FGA tuple in error message | Omit | POST /api/admin/rebac/check |
6.2 Stable reason codesβ
| Code | Meaning | User action hint |
|---|---|---|
OK | Allowed | β |
NO_CAPABILITY | Deny β no relationship | contact_admin |
NOT_SIGNED_IN | Missing/invalid auth | sign_in |
AUTHZ_UNAVAILABLE | PDP timeout/error | retry |
INVALID_REQUEST | Bad resource id / malformed | fix_request |
6.3 Two-tier APIβ
| Tier | Audience | OpenFGA visible? |
|---|---|---|
| Runtime | UI, bots, DA, RAG PEP | No |
| Admin explain | Operators, support | Yes (paths, tuples, provenance) |
7. Workflow-specific resolution (PR #1751)β
7.1 Correct split of responsibilityβ
| Operation | Owner | Mechanism |
|---|---|---|
| Create/update workflow config | BFF | workflow-configs routes + reconcileWorkflowConfigAccess |
| Start/list/cancel/resume run | BFF | /api/workflow-runs + workflow-run-access.ts |
| Pre-save agent access gaps | BFF | check-agent-access + grant via /api/admin/openfga/relationship |
| Orchestrate steps | BFF workflow-engine.ts | Calls DA with user auth headers |
Agent #can_use at DA | DA OpenFGA only | No workflow Mongo β team access via pre-granted tuples or BFF-only delegation |
| DA workflow tools | DA β BFF | WorkflowApiClient /api/workflow-runs |
7.2 workflowDelegatesAgentUse (exists, unused)β
Defined in workflow-config-rebac.ts:
- Agent listed in workflow steps and
workflowRunAllowedByVisibilityfor caller
Action: Wire at POST /api/workflow-runs and optionally before each consumeAgentStream in workflow-engine.ts. Remove DA workflow_execution_authz.py.
7.3 Global workflow gapβ
check-agent-access detects (all users) gaps but grant loop skips them. Spec should decide: org-wide agent grants vs admin-only warning.
8. Recommended phased approachβ
| Phase | Scope | Options | Depends on |
|---|---|---|---|
| 0 β Immediate | PR #1751 cleanup | Remove DA workflow Mongo; keep BFF-only RBAC | β |
| 1 β Hygiene | CI + docs | Option 4 + #1755 UI DRY | β |
| 2 β Facade | BFF routes | Option 1 + Option 5 + error envelope Β§6 | Phase 1 |
| 3 β Runtime API | Bots, DA read paths | Option 2 (#1455) | Phase 2 |
| 4 β RAG convergence | rbac.py thin PEP | Option 1 client in Python or Option 2 HTTP | #1734 |
| 5 β Optional | DA duplicate FGA removal | Option 3 | #1458, #1731 |
9. Open questions for second opinionβ
- DA execution gate: Keep OpenFGA in DA for
agent#use(#1731) or move to BFF-only + signed claims (Option 3)? - Workflow delegation without agent tuples: Is pre-grant on save (modal) sufficient for team workflows, or must runtime delegation work without prior grants?
- Generic vs domain HTTP APIs: One
POST /api/runtime/authorizevs family ofaccess-checkendpoints? - RAG: HTTP client to BFF vs shared Python library duplicating facade logic?
- Service account delegation: How should bots evaluate access for a user without admin UI perms?
- Claim revocation: Required for Option 3, or acceptable 60s TTL?
- Breaking API changes: Version
/api/v2/for error envelope, or migrate in place? - Workflow
tasktype in FGA: Is Mongo visibility a permanent product layer on top of FGA, or should all run access be FGA-only eventually?
10. Acceptance criteria (draft for full spec)β
- No production authz path in
dynamic_agents/**readsworkflow_configsorteamsfrom Mongo. - All new BFF routes use
authorize()facade or documented domain wrapper β CI enforced. - Public API errors use Β§6 reason codes; no
pdp_denied/agent#usein user-facing responses. - Runtime callers (Slack, Webex, DA workflow tools) use BFF HTTP or documented service contract β not admin rebac routes.
-
workflowDelegatesAgentUsewired at run start (and documented for step execution). - RAG plan references same contract as BFF (no third parallel RBAC vocabulary).
-
fga-enforcement-manifest.tsupdated with new surfaces andrebac_enforcedentries. - ADR or #1458 documents dual-gate retirement if DA OpenFGA is removed.
11. References (code & docs)β
Codeβ
ui/src/lib/rbac/shareable-resource.tsui/src/lib/rbac/resource-authz.tsui/src/lib/rbac/openfga.tsui/src/lib/rbac/workflow-config-rebac.tsui/src/lib/rbac/fga-enforcement-manifest.tsui/src/app/api/admin/rebac/check/route.tsui/src/app/api/integrations/slack/.../access-check/route.tsai_platform_engineering/dynamic_agents/src/dynamic_agents/auth/workflow_execution_authz.pyai_platform_engineering/dynamic_agents/src/dynamic_agents/services/builtin_tools.py(WorkflowApiClient)ui/src/lib/server/workflow-engine.tsscripts/validate-fga-create-paths.py
Docsβ
- PDP coverage audit
- RBAC architecture
- Chat execution authz contract
- Unified shareable resource RBAC
- RAG thin PEP plan
- ReBAC policy API contract
12. Instructions for reviewing agentβ
Please evaluate:
- Whether Option 1 + 2 + 4 is the right default combo vs Option 3 early.
- Whether workflow delegation should be FGA tuples (grant on save) vs runtime BFF check only.
- Gaps in threat model for runtime authorize API (service account, OBO, user impersonation).
- Migration risk for error code changes on existing UI/clients.
- Whether this should be one spec or split: (a) facade + enforcement, (b) runtime HTTP API, (c) RAG/DA convergence.
Return: recommended option mix, ordered task list, and any contradictions with #1742 phasing.