MethodPathSummaryAuth
GET/v1/custom-rbac/grantsPage through active or revoked custom-role grantsSession
POST/v1/custom-rbac/grantsAssign the current role revision to another active tenant memberSession
POST/v1/custom-rbac/grants/{grant_id}/revokeAppend a custom-role grant revocation factSession
GET/v1/custom-rbac/permissionsList the tenant-delegable permission catalogSession
GET/v1/custom-rbac/rolesPage through custom roles in the authenticated tenant scopeSession
POST/v1/custom-rbac/rolesCreate a custom role and its first immutable revisionSession
GET/v1/custom-rbac/roles/{role_id}Get a custom role in the authenticated tenant scopeSession
POST/v1/custom-rbac/roles/{role_id}/deactivateDeactivate a custom role with compare-and-swapSession
POST/v1/custom-rbac/roles/{role_id}/publishPublish a new permission revision with compare-and-swapSession
POST/v1/custom-rbac/roles/{role_id}/renameRename a custom role with revision compare-and-swapSession

Contract file:api/control-custom-rbac.openapi.yaml

Operation details

GET /v1/custom-rbac/grants

Page through active or revoked custom-role grants

operationId
listTenantCustomRoleGrants
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Description (from the contract)

The signed cursor freezes grant creation and revocation state at the durable commit-ordered database watermark captured by the first page.

Parameters

listTenantCustomRoleGrants Parameters
NameInTypeRequiredDescription
limitqueryintegerNo—
cursorquerystringNo—
role_idquerystring(uuid)No—
subject_user_idquerystring(uuid)No—
statequerystring: active / revoked / allNo—

Responses

listTenantCustomRoleGrants Responses
StatusDescription
200Stable page of custom-role grants.

Fields:data: array<Grant> page: Page

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/custom-rbac/grants

Assign the current role revision to another active tenant member

operationId
assignTenantCustomRole
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Parameters

assignTenantCustomRole Parameters
NameInTypeRequiredDescription
If-MatchheaderstringYesQuoted positive decimal current role revision, for example "3".
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYes—
X-Step-Up-ProofheaderstringNoOpaque 32-byte base64url MFA proof. Required when the affected permission set contains a catalog entry with step_up_required=true. The server consumes it in the RBAC transaction and binds the use to the operation, authenticated tenant actor and session, target role, subject or grant, expected revision, normalized business payload, and idempotency key. Reusing the proof for a different logical mutation is rejected even when request IDs match.

Request body

application/json · Required:Yes

assignTenantCustomRole Request body
NameTypeRequiredDescription
role_idstring(uuid)Yes—
subject_user_idstring(uuid)Yes—

Responses

assignTenantCustomRole Responses
StatusDescription
201Grant created, or the original response replayed.

Fields:data: Grant

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
404Resource is absent or outside the authenticated tenant
409Idempotency, revision, name, lifecycle, or immutability conflict
413Request body exceeded the configured limit
428A valid bound and unconsumed step-up proof is required
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 428 A precondition is missing: read the resource and send If-Match (or the required proof).
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/custom-rbac/grants/{grant_id}/revoke

Append a custom-role grant revocation fact

operationId
revokeTenantCustomRoleGrant
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Parameters

revokeTenantCustomRoleGrant Parameters
NameInTypeRequiredDescription
grant_idpathstring(uuid)Yes—
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYes—
X-Step-Up-ProofheaderstringNoOpaque 32-byte base64url MFA proof. Required when the affected permission set contains a catalog entry with step_up_required=true. The server consumes it in the RBAC transaction and binds the use to the operation, authenticated tenant actor and session, target role, subject or grant, expected revision, normalized business payload, and idempotency key. Reusing the proof for a different logical mutation is rejected even when request IDs match.

Responses

revokeTenantCustomRoleGrant Responses
StatusDescription
200Revocation appended, or the original response replayed.

Fields:data: Revocation

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
404Resource is absent or outside the authenticated tenant
409Idempotency, revision, name, lifecycle, or immutability conflict
428A valid bound and unconsumed step-up proof is required
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 428 A precondition is missing: read the resource and send If-Match (or the required proof).
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

GET /v1/custom-rbac/permissions

List the tenant-delegable permission catalog

operationId
listTenantDelegablePermissions
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Responses

listTenantDelegablePermissions Responses
StatusDescription
200Delegable permission catalog.

Fields:data: array<Permission>

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

GET /v1/custom-rbac/roles

Page through custom roles in the authenticated tenant scope

operationId
listTenantCustomRoles
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Description (from the contract)

The signed cursor is bound to the authenticated scope and include_deactivated filter, and freezes role creation, revision, and deactivation state at a durable commit-ordered database watermark from the first page.

Parameters

listTenantCustomRoles Parameters
NameInTypeRequiredDescription
limitqueryintegerNo—
cursorquerystringNo—
include_deactivatedquerybooleanNo—

Responses

listTenantCustomRoles Responses
StatusDescription
200Stable page of custom roles.

Fields:data: array<Role> page: Page

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/custom-rbac/roles

Create a custom role and its first immutable revision

operationId
createTenantCustomRole
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Parameters

createTenantCustomRole Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYes—
X-Step-Up-ProofheaderstringNoOpaque 32-byte base64url MFA proof. Required when the affected permission set contains a catalog entry with step_up_required=true. The server consumes it in the RBAC transaction and binds the use to the operation, authenticated tenant actor and session, target role, subject or grant, expected revision, normalized business payload, and idempotency key. Reusing the proof for a different logical mutation is rejected even when request IDs match.

Request body

application/json · Required:Yes

createTenantCustomRole Request body
NameTypeRequiredDescription
namestringYes—
permissionsarray<string>Yes—

Responses

createTenantCustomRole Responses
StatusDescription
201Custom role created, or the original response replayed.

Fields:data: Role

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
409Idempotency, revision, name, lifecycle, or immutability conflict
413Request body exceeded the configured limit
422A requested permission is not tenant delegable
428A valid bound and unconsumed step-up proof is required
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 428 A precondition is missing: read the resource and send If-Match (or the required proof).
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

GET /v1/custom-rbac/roles/{role_id}

Get a custom role in the authenticated tenant scope

operationId
getTenantCustomRole
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Description (from the contract)

Unknown and cross-tenant role IDs return the same 404 response.

Parameters

getTenantCustomRole Parameters
NameInTypeRequiredDescription
role_idpathstring(uuid)Yes—

Responses

getTenantCustomRole Responses
StatusDescription
200Custom role detail.

Fields:data: Role

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
404Resource is absent or outside the authenticated tenant
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/custom-rbac/roles/{role_id}/deactivate

Deactivate a custom role with compare-and-swap

operationId
deactivateTenantCustomRole
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Parameters

deactivateTenantCustomRole Parameters
NameInTypeRequiredDescription
role_idpathstring(uuid)Yes—
If-MatchheaderstringYesQuoted positive decimal current role revision, for example "3".
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYes—
X-Step-Up-ProofheaderstringNoOpaque 32-byte base64url MFA proof. Required when the affected permission set contains a catalog entry with step_up_required=true. The server consumes it in the RBAC transaction and binds the use to the operation, authenticated tenant actor and session, target role, subject or grant, expected revision, normalized business payload, and idempotency key. Reusing the proof for a different logical mutation is rejected even when request IDs match.

Responses

deactivateTenantCustomRole Responses
StatusDescription
200Custom role detail.

Fields:data: Role

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
404Resource is absent or outside the authenticated tenant
409Idempotency, revision, name, lifecycle, or immutability conflict
413Request body exceeded the configured limit
422A requested permission is not tenant delegable
428A valid bound and unconsumed step-up proof is required
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 428 A precondition is missing: read the resource and send If-Match (or the required proof).
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/custom-rbac/roles/{role_id}/publish

Publish a new permission revision with compare-and-swap

operationId
publishTenantCustomRoleRevision
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Parameters

publishTenantCustomRoleRevision Parameters
NameInTypeRequiredDescription
role_idpathstring(uuid)Yes—
If-MatchheaderstringYesQuoted positive decimal current role revision, for example "3".
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYes—
X-Step-Up-ProofheaderstringNoOpaque 32-byte base64url MFA proof. Required when the affected permission set contains a catalog entry with step_up_required=true. The server consumes it in the RBAC transaction and binds the use to the operation, authenticated tenant actor and session, target role, subject or grant, expected revision, normalized business payload, and idempotency key. Reusing the proof for a different logical mutation is rejected even when request IDs match.

Request body

application/json · Required:Yes

publishTenantCustomRoleRevision Request body
NameTypeRequiredDescription
permissionsarray<string>Yes—

Responses

publishTenantCustomRoleRevision Responses
StatusDescription
200Custom role detail.

Fields:data: Role

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
404Resource is absent or outside the authenticated tenant
409Idempotency, revision, name, lifecycle, or immutability conflict
413Request body exceeded the configured limit
422A requested permission is not tenant delegable
428A valid bound and unconsumed step-up proof is required
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 428 A precondition is missing: read the resource and send If-Match (or the required proof).
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list

POST /v1/custom-rbac/roles/{role_id}/rename

Rename a custom role with revision compare-and-swap

operationId
renameTenantCustomRole
Auth
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

All of:identity.roles.manage

Parameters

renameTenantCustomRole Parameters
NameInTypeRequiredDescription
role_idpathstring(uuid)Yes—
If-MatchheaderstringYesQuoted positive decimal current role revision, for example "3".
Idempotency-KeyheaderstringYes—
X-Request-IDheaderstringYes—
TraceparentheaderstringYes—
X-Step-Up-ProofheaderstringNoOpaque 32-byte base64url MFA proof. Required when the affected permission set contains a catalog entry with step_up_required=true. The server consumes it in the RBAC transaction and binds the use to the operation, authenticated tenant actor and session, target role, subject or grant, expected revision, normalized business payload, and idempotency key. Reusing the proof for a different logical mutation is rejected even when request IDs match.

Request body

application/json · Required:Yes

renameTenantCustomRole Request body
NameTypeRequiredDescription
namestringYes—

Responses

renameTenantCustomRole Responses
StatusDescription
200Custom role detail.

Fields:data: Role

400Strict header, query, path, or JSON validation failed
401Authentication is required
403Tenant session or delegation permission was denied
404Resource is absent or outside the authenticated tenant
409Idempotency, revision, name, lifecycle, or immutability conflict
413Request body exceeded the configured limit
422A requested permission is not tenant delegable
428A valid bound and unconsumed step-up proof is required
408Caller cancelled the request
502Storage returned invalid facts or the response exceeded its bound
503Storage or a required dependency is unavailable
504Server-side operation deadline elapsed

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 428 A precondition is missing: read the resource and send If-Match (or the required proof).
  • 503 A dependency is unavailable: retry later with the original Idempotency-Key.

↑ Back to list