docs / access model

Access model

How Fred decides who may do what: Keycloak identity, relationship-based authorization (ReBAC / OpenFGA) as the single enforcement mechanism, and a display-only role catalog for the UI.

Authorization in one line

Authentication is a Keycloak JWT (OIDC), validated on every request. Authorization is ReBAC (OpenFGA), and only ReBAC — evaluated at every endpoint against the caller's relationships to the object (their team, the resource owner, the tag hierarchy).

Roles are not the enforcement layer. The RBAC roles and resource matrix further down are a display-only catalog: the frontend uses them to gate which menus and buttons a user sees. They are never used to allow or deny an operation on the server — that is done exclusively by a ReBAC check. (The former RBAC enforcement path was removed under AUTHZ-01.)

Source: fred-core security/authorization.py · security/permission_catalog.py

Identity & claims

A validated token is decoded into a KeycloakUser:

Token claimKeycloakUser fieldUse
subuidStable user identity key
preferred_usernameusernameDisplay and tracing
emailemailUser profile
resource_access[client].rolesrolesRole labels — feed the display catalog
groupsgroupsTeam membership — drives ReBAC relations

Source: fred-core security/oidc.py (decode_jwt) · security/structure.py (KeycloakUser)

ReBAC — the enforcement model

Fred's OpenFGA schema defines object types, the relations users/teams can hold on them, and the permissions those relations grant. Every protected endpoint resolves to one of these checks.

Organization

Relations: admin, editor (= [user] or admin), viewer (= [user] or editor). Keycloak roles map onto these three. Global capabilities are organization permissions:

PermissionGranted to
can_create_teamadmin
can_create_agenteditor
can_edit_agent_class_pathadmin
can_manage_platform · can_administer_users · can_run_benchmarkadmin
can_read_kpi_globaladmin
can_read_kpi · can_read_logs · can_read_metricsviewer
can_read_opensearch · can_read_knowledge_graph · can_read_contentviewer
can_process_contenteditor

Team

Relations form an owner → manager → member hierarchy, plus an optional public marker:

Agent, tag, document, resource

Source: fred-core security/rebac/schema.fga · security/rebac/rebac_engine.py

The RBAC display catalog

Everything in this section is a frontend display hint, not server-side enforcement. It decides what the UI offers; ReBAC decides what actually happens.

Actions & roles

Actions: create (C), read (R), update (U), delete (D), read:global (G), process (P). Roles:

Keycloak roles admin/editor/viewer are mapped onto the OpenFGA organization relations above; that mapping — not this table — is what enforces.

Resource matrix

Resourceadmineditorviewerservice_agent
tagALLCRUDRR
documentALLCRURR
documents_sourceALLRR
resourceALLCRUDR
tableALLCRUDRR
tables_databaseALLCRUDRR
kpiALLRR
opensearchALLRRR
neo4jALLR
logsALLR
filesALLCRUDCRUD
feedbackALLCC
prompt_completionsALLCC
metricsALLRRR
agentsALLRR
agentALLR
sessionsALLCRUDCRUD
message_attachmentsALLC,RCRUD
mcp_serversALLCRUR
userALLRR
teamALLR
organizationALLR
ALL = all six actions · CRUD = create/read/update/delete · CRU = create/read/update · C = create · R = read · — = none.

Source: fred-core security/models.py (Action, Resource) · security/permission_catalog.py (ROLE_CAPABILITIES)

Endpoint enforcement

Authentication is a Keycloak JWT everywhere. Authorization is a ReBAC check keyed to the surface:

SurfaceAuthorization (ReBAC)
control-plane · teamsTeam permissions — can_read, can_update_info, can_read_members, can_administer_*
control-plane · platform, import/export, agent class pathOrganization can_manage_platform
control-plane · global KPIsOrganization can_read_kpi_global
control-plane · sessions & historyTeam + owner scoping — session.user_id == uid and matching team_id
control-plane · evaluationsTeam can_update_agents / can_read
fred-agents · execute / streamPod-side team can_read on a mandatory team_id, per request
knowledge-flow · tags, documents, resourcesObject-level tag / document / resource permissions
knowledge-flow · content, logs, statisticsOrganization can_read_content / can_process_content / can_read_logs
health / readinessPublic — no auth

Source: control-plane teams/service.py, product/service.py, evaluations/api.py · knowledge-flow features/* · fred-runtime app/agent_app.py

Execution authorization

Agent execution is team-scoped and authorized at the pod. There is no signed grant or capability token: the control plane issues none. Identity is the Keycloak JWT, and the agent pod runs an OpenFGA check on the caller's team_id for every request before executing. The ExecutionGrantAction values (execute, resume) are action labels, not tokens.

Source: fred-sdk contracts/execution.py · fred-runtime app/agent_app.py

ReBAC-disabled mode

When OIDC is off or ReBAC is disabled, Fred loads a no-op engine: has_permission() returns True, and lookups return a "disabled" marker so services skip object-level filtering. The deployment is effectively open — intended for local development, never production.

Source: fred-core security/rebac/noop_engine.py · security/rebac/rebac_factory.py