Skip to content

Permissions API

Permission endpoints are nested under tenants. All endpoints require authentication and enforce tenant scope for scoped API keys.

Endpoints

MethodPathDescription
GET/api/v1/tenants/:id/permissionsGet resolved permissions
POST/api/v1/tenants/:id/permissionsCreate permission policy
PATCH/api/v1/tenants/:id/permissions/:policyIdUpdate permission policy
DELETE/api/v1/tenants/:id/permissions/:policyIdDelete permission policy

Get Resolved Permissions

GET /api/v1/tenants/:id/permissions

Returns resolved permissions with delegation mode and source tracking applied.

Response: 200 OK

{
"manage_users": {
"key": "manage_users",
"value": true,
"mode": "LOCKED",
"source_tenant_id": "root-uuid",
"locked": true,
"delegated": false
},
"custom_branding": {
"key": "custom_branding",
"value": true,
"mode": "DELEGATED",
"source_tenant_id": "msp-uuid",
"locked": false,
"delegated": true
}
}

Each resolved entry:

FieldDescription
keyPermission identifier
valueEffective value (typically boolean)
modeLOCKED, INHERITED, or DELEGATED
source_tenant_idWhich ancestor created this policy
lockedtrue if mode is LOCKED
delegatedtrue if mode is DELEGATED

Create Permission

POST /api/v1/tenants/:id/permissions

Body:

{
"key": "manage_users",
"value": true,
"mode": "LOCKED",
"revocation_mode": "CASCADE"
}
FieldValuesDefaultDescription
keystringRequiredPermission identifier
valueanytruePermission value
modeLOCKED, INHERITED, DELEGATEDINHERITEDHow the permission flows down the tree
revocation_modeCASCADE, SOFT, PERMANENTCASCADEWhat happens when deleted

Delegation Modes

ModeBehavior
LOCKEDSet once, immutable by any descendant
INHERITEDFlows down, descendants can override the value
DELEGATEDFlows down, descendants can override and re-delegate

Revocation Modes

ModeBehavior
CASCADEDeletes from this tenant and all descendants
SOFTDeletes only from this tenant; children keep copies
PERMANENTCannot be deleted (returns 403)

Response: 201 Created — returns the permission policy.


Update Permission

PATCH /api/v1/tenants/:id/permissions/:policyId

Body (all fields optional):

{
"value": true,
"mode": "DELEGATED",
"revocation_mode": "SOFT"
}

Response: 200 OK — returns the updated policy.


Delete Permission

DELETE /api/v1/tenants/:id/permissions/:policyId

Behavior depends on the policy’s revocation mode:

  • CASCADE — deletes from this tenant and all descendants
  • SOFT — deletes only from this tenant
  • PERMANENT — returns 403 PERMISSION_REVOCATION_DENIED

Response: 204 No Content


Error Responses

CodeStatusDescription
PERMISSION_LOCKED409Permission is locked by an ancestor
PERMISSION_REVOCATION_DENIED403Permission has PERMANENT revocation mode
TENANT_NOT_FOUND404Tenant ID does not exist
NOT_FOUND404Permission policy not found
{
"error": {
"code": "PERMISSION_REVOCATION_DENIED",
"message": "Permission policy has PERMANENT revocation mode and cannot be deleted"
}
}