Roles API
Quick example
- curl
- Python
- Node.js
# Create a custom role
curl "$TRINITITE_BASE/v1/roles" \
-H "Authorization: Bearer $SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "GuardianAuthor",
"description": "Can author and finalize Guardians, but cannot deploy",
"permissions": ["guardians:create", "guardians:update", "policies:read", "test_suites:run"]
}'
import os, requests
requests.post(f"{os.environ['TRINITITE_BASE']}/v1/roles",
headers={"Authorization": f"Bearer {os.environ['SESSION_TOKEN']}"},
json={"name": "GuardianAuthor",
"description": "Can author and finalize Guardians, but cannot deploy",
"permissions": ["guardians:create", "guardians:update", "policies:read", "test_suites:run"]})
await fetch(`${process.env.TRINITITE_BASE}/v1/roles`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.SESSION_TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'GuardianAuthor',
description: 'Can author and finalize Guardians, but cannot deploy',
permissions: ['guardians:create', 'guardians:update', 'policies:read', 'test_suites:run'],
}),
});
Overview
A Role is a named bundle of permission strings. A user's effective permissions are the union of permissions across all their assigned roles. Permissions take the form resource:action and may include wildcards.
Authentication: session token only (Authorization: Bearer <session_token>).
System roles
Four built-in roles ship pre-defined and cannot be edited or deleted. They are listed first in GET /v1/roles and identified by is_system_role: true.
| Role | Description |
|---|---|
admin | Full platform access (*:*) |
auditor | Read-only access to compliance, attestation, audit-log, and report surfaces |
developer | Standard operator role for Guardians, policies, training, and proxy traffic |
viewer | Read-only access to most surfaces |
Permission catalogue
Permissions are resource:action strings. Any role — system or custom — is just a list of these.
| Permission | Grants |
|---|---|
guardians:read / :create / :write / :admin | List, view, and call Guardians; create; update / delete; power operations |
policies:read / :write | Policy documents and their nodes |
mcp:read / :write | MCP gateway servers, bindings, OAuth |
nhi:read / :write | Non-Human Identities |
compliance:read / :write | Compliance frameworks, evidence, DSR |
reports:read / :write | Enterprise reports |
skills:read / :write | Skill Vault |
cli:read / :create | CLI Firewall (read; execute) |
logs:read | Glass Box Ledger |
audit_logs:read | Auditor activity / governance audit log |
analytics:read | Analytics rollups |
users:create / :read / :update / :delete | User CRUD |
roles:create / :read / :update / :delete | Role CRUD |
organization:update | Update organization profile |
api_keys:read / :write | API key inventory |
Wildcards
<resource>:*— all actions on a single resource (e.g.guardians:*).*or*:*— all actions on all resources. Reserved for the built-inadminsystem role and explicitly elevated keys.
Endpoints
| Method | Path | Permission |
|---|---|---|
GET | /v1/roles | roles:read |
GET | /v1/roles/{role_id} | roles:read |
POST | /v1/roles | roles:create |
PATCH | /v1/roles/{role_id} | roles:update |
DELETE | /v1/roles/{role_id} | roles:delete |
System roles cannot be modified or deleted via the API — calls to PATCH / DELETE against an is_system_role: true role return 403 forbidden.
GET /v1/roles
{
"roles": [
{
"role_id": "role_system_admin",
"role_name": "admin",
"description": "Full administrative access.",
"permissions": ["*"],
"is_system_role": true
},
{
"role_id": "role_system_auditor",
"role_name": "auditor",
"description": "Read-only access to compliance, attestation, audit, and reports.",
"permissions": [
"compliance:read",
"audit_logs:read",
"logs:read",
"reports:read"
],
"is_system_role": true
},
{
"role_id": "role_01JF8RRO1A2B3C4D5E6F7G8H9I",
"role_name": "compliance-reviewer",
"description": "Read governance logs and analytics.",
"permissions": ["logs:read", "analytics:read"],
"is_system_role": false
}
]
}
GET /v1/roles/{role_id}
Returns a single role object with the same schema as a list row.
POST /v1/roles
Create a custom role.
{
"role_name": "compliance-reviewer",
"description": "Can read governance logs and download compliance reports.",
"permissions": ["logs:read", "analytics:read", "compliance:read", "reports:read"]
}
| Field | Type | Required | Description |
|---|---|---|---|
role_name | string | Yes | Unique name within your organization |
description | string | Yes | Human-readable description |
permissions | string[] | Yes | Permission strings (resource:action) |
Response — 201 Created:
{
"role_id": "role_01JF8RRO2B3C4D5E6F7G8H9I0J",
"role_name": "compliance-reviewer",
"description": "Can read governance logs and download compliance reports.",
"permissions": ["logs:read", "analytics:read", "compliance:read", "reports:read"],
"is_system_role": false
}
PATCH /v1/roles/{role_id}
Partial update on a custom role. The permissions array, when provided, replaces the full list (not merges).
{
"description": "Read governance logs, analytics, and compliance posture.",
"permissions": ["logs:read", "analytics:read", "compliance:read", "reports:read", "guardians:read"]
}
| Field | Type | Description |
|---|---|---|
description | string | Updated description |
permissions | string[] | Replacement permission list |
Returns the updated role object.
DELETE /v1/roles/{role_id}
Delete a custom role. Any users currently assigned the role have it removed automatically.
{ "message": "Role deleted successfully.", "role_id": "role_01JF8RRO2B3C4D5E6F7G8H9I0J" }
Errors
| HTTP | error.code | Cause |
|---|---|---|
400 | validation_error | Body or query failed schema validation |
400 | bad_request | Unknown permission string |
401 | unauthenticated | Missing or invalid session token |
403 | forbidden | Insufficient permissions, or attempt to modify a system role |
404 | not_found | Role not found in your organization |
409 | conflict | A role with that name already exists |
Next steps
- Assign roles to users → Users API
- Issue scoped API keys → Authentication
- Invite a user with a pre-assigned role → Invitations API