Skip to content

IAM — Roles

A role is a named bundle of access rules — CRN patterns with the actions they allow or deny — held by every account paired to it, and capped by the tenant's rootAccess. Effective access is assembled per request from the rules on the account plus every role it holds, directly or through a user group — so a change lands on the holders' next request, with no new token.

The ceiling itself is set on the tenant; user groups hand out several roles at once, and require2FA forces the holders through the second-factor flow in authentication. Pairing and rule changes are published as IAM_ROLE_PAIR_USER and IAM_ROLE_UPDATE.

POSTCreate a role/api/v1/role
GETList roles/api/v1/role
GETRead a role/api/v1/role/:roleId
DELETEDelete a role/api/v1/role/:roleId
PATCHUpdate a role/api/v1/role/:roleId
PUTReplace a role/api/v1/role/:roleId
POSTAdd users to a role/api/v1/role/:roleId/user
GETList role holders/api/v1/role/:roleId/user
DELETERemove users from a role/api/v1/role/:roleId/user

Create a role

The role's access is checked against the tenant's rootAccess, and a rule reaching beyond it is refused with both sets in the error. tenantId is only needed when the caller's own access spans more than one tenant.

POST/api/v1/role

Body

NameDescription
namestringDisplay name for the role
min length 1 · max length 64
descriptionstringoptionalOptional description of the role's purpose
accessarrayoptionalAccess policies assigned to members of this role
Default: []
identifierThe resource this policy applies to
Alternative 1Resource identifier pattern (CRN), may include wildcards
Alternative 2Resource identifier pattern (CRN), may include wildcards
Alternative 3Resource identifier pattern (CRN), may include wildcards
Alternative 4Resource identifier pattern (CRN), may include wildcards
Alternative 5Resource identifier pattern (CRN), may include wildcards
Alternative 6Resource identifier pattern (CRN), may include wildcards
effectenumAccess policy effect — either allow or deny
Possible values: deny, allow
actionsarrayList of actions permitted by this policy
policyobjectoptionalAdditional constraints for this access policy
enforce2FAbooleanoptionalRequires the subject to have 2FA active before this access is granted
targetoptionalWhere a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Alternative 1Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Possible values: user, role, group
Alternative 2Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
isOwnerbooleanoptionalMarks an owner-relative rule, written as crn#tenant:<id>.user:* and rebound to the holder's own account when the access list is assembled — how a shared role says "your own account" without naming anyone.
require2FAbooleanoptionalWhether members of this role must have two-factor authentication enabled
Default: false
tenantIdstringoptionalTenant to create this role in — defaults to the authenticated user's tenant
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Response

NameDescription
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
400The requested role permissions exceed what is allowed for this tenantcode: ROLE_NO_SUBSET_ERROR
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

List roles

The roles of the caller's tenant; it takes read on crn#tenant:<id>.role:*, not on each role. A caller whose access spans several tenants gets a conflict instead — narrow the request with X-Tenant-Id.

GET/api/v1/role

Response

NameDescription
namestringDisplay name of the role
min length 1 · max length 64
descriptionstringoptionalHuman-readable description of the role's purpose
accessarrayoptionalAccess policies assigned to members of this role
Default: []
identifierThe resource this policy applies to
Alternative 1Resource identifier pattern (CRN), may include wildcards
Alternative 2Resource identifier pattern (CRN), may include wildcards
Alternative 3Resource identifier pattern (CRN), may include wildcards
Alternative 4Resource identifier pattern (CRN), may include wildcards
Alternative 5Resource identifier pattern (CRN), may include wildcards
Alternative 6Resource identifier pattern (CRN), may include wildcards
effectenumAccess policy effect — either allow or deny
Possible values: deny, allow
actionsarrayList of actions permitted by this policy
policyobjectoptionalAdditional constraints for this access policy
enforce2FAbooleanoptionalRequires the subject to have 2FA active before this access is granted
targetoptionalWhere a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Alternative 1Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Possible values: user, role, group
Alternative 2Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
isOwnerbooleanoptionalMarks an owner-relative rule, written as crn#tenant:<id>.user:* and rebound to the holder's own account when the access list is assembled — how a shared role says "your own account" without naming anyone.
require2FAbooleanoptionalWhether members of this role must have two-factor authentication enabled
Default: false
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
createdBystringResource identifier of the entity that created this resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Read a role

The role with the access rules it grants. Who holds it is a separate call, GET /role/{roleId}/user.

GET/api/v1/role/Yk3pL7rWq2

Path Parameters

NameDescription
roleIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Response

NameDescription
namestringDisplay name of the role
min length 1 · max length 64
descriptionstringoptionalHuman-readable description of the role's purpose
accessarrayoptionalAccess policies assigned to members of this role
Default: []
identifierThe resource this policy applies to
Alternative 1Resource identifier pattern (CRN), may include wildcards
Alternative 2Resource identifier pattern (CRN), may include wildcards
Alternative 3Resource identifier pattern (CRN), may include wildcards
Alternative 4Resource identifier pattern (CRN), may include wildcards
Alternative 5Resource identifier pattern (CRN), may include wildcards
Alternative 6Resource identifier pattern (CRN), may include wildcards
effectenumAccess policy effect — either allow or deny
Possible values: deny, allow
actionsarrayList of actions permitted by this policy
policyobjectoptionalAdditional constraints for this access policy
enforce2FAbooleanoptionalRequires the subject to have 2FA active before this access is granted
targetoptionalWhere a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Alternative 1Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Possible values: user, role, group
Alternative 2Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
isOwnerbooleanoptionalMarks an owner-relative rule, written as crn#tenant:<id>.user:* and rebound to the holder's own account when the access list is assembled — how a shared role says "your own account" without naming anyone.
require2FAbooleanoptionalWhether members of this role must have two-factor authentication enabled
Default: false
resourceIdentifierstringUnique Coldwave resource name (CRN) that identifies a resource
createdBystringResource identifier of the entity that created this resource

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404The requested role could not be found
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Delete a role

Unpairs every user holding the role before removing it, so all of them lose the access it granted at that moment. The accounts themselves are untouched.

DELETE/api/v1/role/Yk3pL7rWq2

Path Parameters

NameDescription
roleIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404The requested role could not be found
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Update a role

Writes only the fields present. access replaces the rule set as a whole rather than merging into it and is still capped by the tenant's rootAccess — leave it out to keep the rules as they are.

PATCH/api/v1/role/Yk3pL7rWq2

Path Parameters

NameDescription
roleIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Body

NameDescription
namestringoptionalNew display name for the role
min length 1 · max length 64
descriptionstringoptionalUpdated description of the role's purpose
accessarrayoptionalReplacement access policies for this role — replaces the existing set
identifierThe resource this policy applies to
Alternative 1Resource identifier pattern (CRN), may include wildcards
Alternative 2Resource identifier pattern (CRN), may include wildcards
Alternative 3Resource identifier pattern (CRN), may include wildcards
Alternative 4Resource identifier pattern (CRN), may include wildcards
Alternative 5Resource identifier pattern (CRN), may include wildcards
Alternative 6Resource identifier pattern (CRN), may include wildcards
effectenumAccess policy effect — either allow or deny
Possible values: deny, allow
actionsarrayList of actions permitted by this policy
policyobjectoptionalAdditional constraints for this access policy
enforce2FAbooleanoptionalRequires the subject to have 2FA active before this access is granted
targetoptionalWhere a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Alternative 1Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Possible values: user, role, group
Alternative 2Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
isOwnerbooleanoptionalMarks an owner-relative rule, written as crn#tenant:<id>.user:* and rebound to the holder's own account when the access list is assembled — how a shared role says "your own account" without naming anyone.
require2FAbooleanoptionalWhether members of this role must have two-factor authentication enabled

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404The requested role could not be found
400The requested role permissions exceed what is allowed for this tenantcode: ROLE_NO_SUBSET_ERROR
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Replace a role

Overwrites the whole role: an omitted access leaves it with no rules at all and an omitted require2FA falls back to false. Only the original createdBy survives the write.

PUT/api/v1/role/Yk3pL7rWq2

Path Parameters

NameDescription
roleIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Body

NameDescription
namestringDisplay name for the role
min length 1 · max length 64
descriptionstringoptionalOptional description of the role's purpose
accessarrayoptionalAccess policies assigned to members of this role
Default: []
identifierThe resource this policy applies to
Alternative 1Resource identifier pattern (CRN), may include wildcards
Alternative 2Resource identifier pattern (CRN), may include wildcards
Alternative 3Resource identifier pattern (CRN), may include wildcards
Alternative 4Resource identifier pattern (CRN), may include wildcards
Alternative 5Resource identifier pattern (CRN), may include wildcards
Alternative 6Resource identifier pattern (CRN), may include wildcards
effectenumAccess policy effect — either allow or deny
Possible values: deny, allow
actionsarrayList of actions permitted by this policy
policyobjectoptionalAdditional constraints for this access policy
enforce2FAbooleanoptionalRequires the subject to have 2FA active before this access is granted
targetoptionalWhere a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Alternative 1Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
Possible values: user, role, group
Alternative 2Where a device claimed under this rule lands: the kind of owner — user, role or group — or a CRN naming one outright. Only meaningful on a .pair rule.
isOwnerbooleanoptionalMarks an owner-relative rule, written as crn#tenant:<id>.user:* and rebound to the holder's own account when the access list is assembled — how a shared role says "your own account" without naming anyone.
require2FAbooleanoptionalWhether members of this role must have two-factor authentication enabled
Default: false
tenantIdstringoptionalTenant to create this role in — defaults to the authenticated user's tenant
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404The requested role could not be found
400The requested role permissions exceed what is allowed for this tenantcode: ROLE_NO_SUBSET_ERROR
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Add users to a role

Takes share on the role and read on every account named — handing a role out is acting on the account that receives it. user is one CRN or a list, each inside the caller's own tenant; a user who already holds the role is left unchanged.

POST/api/v1/role/Yk3pL7rWq2/user

Path Parameters

NameDescription
roleIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Body

NameDescription
userOne or more user resource identifiers to assign to this role
Alternative 1stringUnique Coldwave resource name (CRN) that identifies a resource
Alternative 2arrayOne or more user resource identifiers to assign to this role

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404The requested role could not be found
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

List role holders

The CRNs of the users paired to the role. It takes read on the role itself, not on each account it returns.

GET/api/v1/role/Yk3pL7rWq2/user

Path Parameters

NameDescription
roleIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Response

NameDescription

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404The requested role could not be found
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50

Remove users from a role

The same privilege as handing the role out: share on the role and read on every account named. Removing someone who never held it is a no-op, not a conflict.

DELETE/api/v1/role/Yk3pL7rWq2/user

Path Parameters

NameDescription
roleIdstringResource id: Base58 (9–10 characters) or a 16-character Crockford snowflake. Not an RFC 4122 UUID.
Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$

Body

NameDescription
userOne or more user resource identifiers to assign to this role
Alternative 1stringUnique Coldwave resource name (CRN) that identifies a resource
Alternative 2arrayOne or more user resource identifiers to assign to this role

Errors

StatusDescriptionBody
403You do not have permission to perform this action
404The requested role could not be found
409A tenant with the given name already existscode: IAM_TENANT_CONFLICT_ERROR
400The request did not match the schema for this endpoint. The details field carries the specific failures.error: Validation Error
401No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key.error: string
500The request failed for a reason that is not the caller's to fix. Safe to retry.error: string, message: string, statusCode: 50