Roles
A role is a group of users within a tenant. Roles can be granted permissions on datasets, which apply to their members. This enables fine-grained access control within organizations and makes it easier to manage permissions for different teams.Role-based permissions — When a role is granted a permission on a dataset, all users assigned to that role inherit that permission.
Role Concept
Roles are created by the tenant owner, or by anyone holding themanage_users capability in that tenant, and are scoped to that specific tenant. The role belongs to exactly one tenant as soon as it’s created. Because of that foreign-key link, a role can’t be moved or shared with another tenant; you would need to create a new role under the other tenant instead.
Users can be assigned to multiple roles within their tenant, and roles can contain multiple users. This many-to-many relationship allows flexible permission management across teams.
Role-Based Permissions
When a role is granted a permission on a dataset, all users assigned to that role inherit that permission. Users receive the union of their direct permissions, their agents’ direct permissions, tenant-level permissions, and role-level permissions, narrowed to their active tenant. Roles allow you to create permission groups like “editors” or “viewers” within a tenant, making it easier to manage access for different teams without granting permissions to individual users.Role Model Fields
Role Model Fields
The Role model defines what gets stored in the SQL database. The
roles table contains:id: Unique identifier (UUID primary key, references principals.id)name: Human-readable name (unique within tenant)tenant_id: ID of the tenant this role belongs to (required)
Role Creation
Role Creation
create_role(role_name, owner_id): Creates a new role in the requester’s current tenant. Requires themanage_userscapability in that tenant; the tenant owner always qualifies.add_user_to_role(user_id, role_id, owner_id): Assigns a user to a role. Requiresmanage_usersin the role’s tenant and that the requester holds every capability the role carries (see Roles Can Carry Capabilities); the tenant owner always qualifies.
Role and Member Deletion
Role and Member Deletion
delete_role(role_id, owner_id): Deletes a role, removes all user-role memberships for that role, revokes dataset permissions granted to the role principal, and removes the capabilities granted to it. Exposed viaDELETE /api/v1/permissions/roles/{role_id}.remove_user_from_role(user_id, role_id, owner_id): Removes a user from a specific role without removing them from the tenant. Exposed viaDELETE /api/v1/permissions/users/{user_id}/roles.
remove_user_from_tenant (see Tenants) only when you want to remove a user from the entire tenant. That operation also strips the user from all roles in the tenant and revokes their direct dataset permissions for tenant-owned datasets and the capabilities granted to them directly in that tenant, and does the same for the agents they created.Limitations
Limitations
- Roles are tenant-scoped and cannot cross tenants
- API endpoints for role management
Roles Can Carry Capabilities
Besides dataset permissions, a role can be granted capabilities — tenant-scoped actions such asmanage_users. Every member of the role then holds them in that role’s tenant, which is how administration is delegated without making anyone a tenant owner:
tenant_id query parameter is ignored for a role principal — a role already knows its tenant — and deleting the role removes its capability grants with it.
Assigning such a role is itself restricted: add_user_to_role requires the caller to hold every capability the role carries, on top of manage_users in the tenant. Otherwise manage_users would be a path to the rest of the catalog — a caller could simply add themselves to a role that holds grant_capabilities. A caller who does not hold one of them receives 403, with a message naming the capabilities they are missing.
Role Management
Tenant owners can:- Create roles within their tenant
- Assign users to roles
- Remove users from roles
- Grant permissions to roles
- Delete roles
manage_users capability in the role’s tenant, which the owner always holds and which can be granted to a role or to a user directly — creating and assigning used to be restricted to the owner and now follow the same rule as deletion and removal. Assigning a role carries the extra restriction described above.
The Deprecated admin Role-Name Fallback
Before capabilities existed, a role’s name was how user management was authorized. To keep tenants that have no capability rows yet working, a role literally named admin still passes every capability check by name alone.
Because an admin role counts as carrying all three capabilities, only a caller who holds all three, such as the tenant owner, can add users to it.
Role Visibility
Reading roles is scoped to membership, independently of who may administer them:- Roles you belong to —
GET /api/v1/permissions/tenants/{tenant_id}/rolesreturns200for any authenticated caller when the tenant exists (a nonexistenttenant_idstill returns404). Callers who are the tenant owner or hold themanage_userscapability see every role in the tenant; everyone else sees only the roles they are a member of. A caller who belongs to no role in that tenant — including a caller who passes atenant_idfor a tenant they are not part of — receives an empty list rather than an error. - Members of those roles —
GET /api/v1/permissions/tenants/{tenant_id}/roles/{role_id}/usersis visible to members of the role itself, so users can see who shares their roles. A caller who is not a member and lacks themanage_userscapability receives403. The role is resolved within the tenant in the path, so arole_idbelonging to another tenant returns404instead of that tenant’s members. - The roles held by one user —
GET /api/v1/permissions/tenants/{tenant_id}/roles/users/{user_id}requires tenant ownership or themanage_userscapability in that tenant; a caller with neither receives403. The target user is resolved within the tenant in the path, so auser_idthat is not a member of it returns404rather than that user’s roles elsewhere. The response lists only roles belonging to the tenant in the path, so a user who is a member of several tenants never leaks the other tenants’ roles into it. A tenant member who holds no role there receives an empty list — empty means “a member with no roles”,404means “not a member”. - The full tenant user directory —
GET /api/v1/permissions/tenants/{tenant_id}/usersstill requires tenant ownership or themanage_userscapability. Role membership alone does not grant it. - The datasets granted to a role —
GET /api/v1/permissions/principals/{principal_id}/datasetsreturns the datasets a principal holds a permission on, so you can answer “which datasets does this team have?”. The optionalpermission_namequery parameter selects which permission to list and defaults toread; the other accepted values arewrite,delete, andshare. For a roleprincipal_id, the endpoint is visible to members of that role, so users can list the datasets of the roles they belong to; a non-member who is not the tenant owner and lacks themanage_userscapability receives403. The role is resolved within the caller’s current tenant, so arole_idbelonging to another tenant returns404rather than revealing that tenant’s datasets. The response is a JSON list of dataset objects, and it is always narrowed to the caller’s current tenant.
Common Role Patterns
Roles are typically organized around job functions or responsibilities:- Editors — Can modify content and run cognify operations
- Viewers — Can only read and search data
- Administrators — Can manage permissions and users; grant this role the
manage_userscapability rather than relying on the deprecatedadminname fallback - Project Managers — Can access specific project datasets
- Reviewers — Can read and provide feedback on content
Permission Inheritance Hierarchy
Users receive permissions through a three-level hierarchy:- Direct permissions — Explicitly granted to the user
- Role permissions — Inherited through role memberships
- Tenant permissions — Inherited through tenant membership
Best Practices
- Create meaningful role names — Use descriptive names that reflect the role’s purpose
- Keep roles focused — Each role should have a clear, specific purpose
- Regular role reviews — Periodically review and update role assignments
- Document role purposes — Keep clear documentation of what each role is for
- Principle of least privilege — Grant only the minimum permissions necessary
Role vs Tenant Permissions
- Tenant permissions — Broad, organization-wide access
- Role permissions — Specific, team-based access within the tenant
- Direct permissions — Individual, user-specific access
ACL
Learn how permissions are stored and checked
Snippets
See practical snippets of role-based permissions