Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.emergence.ai/llms.txt

Use this file to discover all available pages before exploring further.

Configure Roles and Permissions

CRAFT uses OpenFGA for Relationship-Based Access Control (ReBAC). This guide covers setting up roles, assigning permissions, and configuring the permission inheritance model across organizations, projects, and resources.

Prerequisites

Before you begin, ensure you have:
  • A running CRAFT with the Governance service bootstrapped
  • Administrative access (the admin or owner role on the target organization)
  • A valid JWT token for the admin user
  • The OpenFGA schema loaded during Governance bootstrap

How Permissions Work

The platform uses a relationship-based model rather than traditional role-based access control. Permissions are computed at query time from relationships between users, roles, and resources.
User --[role]--> Organization --[parent]--> Project --[parent]--> Resource

Role Hierarchy

RoleScopeCapabilities
ownerOrganizationFull control, can transfer ownership, manage all settings
adminOrganization / ProjectManage users, projects, settings. Cannot transfer organization ownership
memberProjectStandard access to project resources
developerProjectCreate and modify agents, data connections, workflows
operatorProjectDeploy, schedule, and monitor resources
viewerProjectRead-only access to all resources

Computed Permissions

Permissions are derived from roles via the OpenFGA schema:
Permissionowneradminmemberdeveloperoperatorviewer
can_readYesYesYesYesYesYes
can_writeYesYesYesYesNoNo
can_deleteYesYesNoNoNoNo
can_executeYesYesYesYesYesNo
can_manage_secretsYesYesNoNoNoNo

Step 1: Understand the OpenFGA Schema

The permission model is defined in the OpenFGA Schema DSL. The schema lives at:
packages/em_runtime_governance/schema/openfga-schema.fga
Key type definitions:
type organization
  relations
    define owner: [user]
    define admin: [user] or owner
    define member: [user] or admin

type project
  relations
    define parent: [organization]
    define admin: [user] or admin from parent
    define developer: [user] or admin
    define operator: [user] or admin
    define viewer: [user] or developer or operator
    define can_read: viewer or member from parent
    define can_write: developer or admin
    define can_delete: admin
    define can_execute: operator or developer or admin
The runtime JSON version at openfga-schema.json is what the Governance service reads at startup. After editing the .fga file, run ./scripts/generate-openfga-schema.sh to regenerate the JSON.

Step 2: Assign Organization Roles

Assign roles to users at the organization level using the Governance API.
# Assign the admin role to a user
curl -X POST "https://<platform-host>:8001/governance/organizations/<org-id>/members" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "<user-id>",
    "role": "admin"
  }'

Step 3: Assign Project Roles

Project roles provide finer-grained control within an organization.
# Assign the developer role on a specific project
curl -X POST "https://<platform-host>:8001/governance/projects/<project-id>/members" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Project-ID: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "<user-id>",
    "role": "developer"
  }'

Permission Inheritance

Roles inherit downward through the hierarchy:
1

Organization owner

Automatically has admin-level permissions on all projects and resources within the organization.
2

Organization admin

Automatically has admin-level permissions on all projects. Can create and delete projects.
3

Project developer

Has can_read, can_write, and can_execute on all resources within the specific project. Cannot delete resources or manage secrets.
4

Project viewer

Has can_read only. Cannot modify, execute, or delete any resource.

Step 4: Verify Permissions

Check whether a user has a specific permission on a resource:
# Check if user can write to an agent
curl -X POST "https://<platform-host>:8001/governance/permissions/check" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "<user-id>",
    "permission": "can_write",
    "resource_type": "agent",
    "resource_id": "<agent-id>"
  }'
Response:
{
  "allowed": true,
  "resolution": {
    "role": "developer",
    "inherited_from": "project:<project-id>"
  }
}

Common Permission Patterns

Assign viewer on the project containing data connections and dashboards. Users can run queries via Data Insights but cannot modify data connections or agent configurations.
Assign operator on the target project. Operators can deploy agents, trigger schedules, and monitor health, but cannot modify agent code or data connection credentials.
Create Keycloak client credentials and assign developer or operator on the target project. Service accounts authenticate via client credentials grant and have the same permission model as human users.
A user can have different roles on different projects within the same organization. Assign roles per project to implement least-privilege access.

Integration with SSO Groups

When SSO is configured, IdP groups map through Keycloak to OpenFGA:
IdP Group -> Keycloak Group -> OpenFGA Relation (role assignment)
This pipeline automates role assignment when users are provisioned via SSO. See the SSO Integration guide for configuring the IdP side.

Schema Modifications

Adding new permissions to the OpenFGA schema is safe. Renaming or removing existing permissions is a breaking change — coordinate schema and code changes in the same PR.
To add a new permission:
  1. Edit packages/em_runtime_governance/schema/openfga-schema.fga
  2. Run ./scripts/generate-openfga-schema.sh to regenerate the runtime JSON
  3. Update the Permissions class in packages/em_runtime_common/src/common/permissions.py
  4. Run make dev-sync to regenerate SDKs

Troubleshooting

Verify the OpenFGA schema is loaded by checking Governance bootstrap logs. Ensure the user’s JWT contains the correct groups claim. Confirm the user has been assigned a role on the target project.
Check that the project has a parent relationship to the organization in OpenFGA. This is set automatically when projects are created via the Governance API.
OpenFGA evaluates permissions at query time — there is no caching delay. If changes are not reflected, verify the role assignment was successful by listing members on the project.

Next Steps

SSO Integration

Configure SSO to automate group-to-role mapping from your IdP.

Authorization Deep Dive

Learn about the full OpenFGA schema and computed permissions model.

Multi-Tenancy

Understand how permissions integrate with the multi-tenant architecture.

Security Overview

Review the complete security model including authentication and data protection.