Appearance
IAM — User Groups
The roles a group carries and the accounts in it are links under the group CRN, not fields on the entry. A role reached through a group is held just like one paired by hand, and membership is resolved per request — a change lands on the next call, without a new token.
A rule on <usergroup>.users expands into one rule per member — read, update and delete, never create — while a rule naming the group alone produces none, so seeing a group and reaching the accounts in it stay separate rights. Changes raise IAM_USERGROUP_PAIR_ROLE and IAM_USERGROUP_PAIR_USER with their UNPAIR counterparts.
| POST | Create a user group/api/v1/usergroup |
| GET | List user groups/api/v1/usergroup |
| GET | Read a user group/api/v1/usergroup/:usergroupId |
| PATCH | Update a user group/api/v1/usergroup/:usergroupId |
| DELETE | Delete a user group/api/v1/usergroup/:usergroupId |
| GET | List the group's roles/api/v1/usergroup/:usergroupId/roles |
| POST | Add roles to a group/api/v1/usergroup/:usergroupId/roles |
| DELETE | Remove roles from a group/api/v1/usergroup/:usergroupId/roles |
| GET | List the group's members/api/v1/usergroup/:usergroupId/users |
| POST | Add members to a group/api/v1/usergroup/:usergroupId/users |
| DELETE | Remove members from a group/api/v1/usergroup/:usergroupId/users |
Create a user group
A user group is a named bundle of roles: it starts empty, and roles and members are added through its sub-routes. tenantId is only needed when the caller's access spans more than one tenant.
POST
/api/v1/usergroupBody
| Name | Description |
|---|---|
namestring | 1 to 64 characters and the only field the body requires; a name already used in the tenant is not refused. min length 1 · max length 64 |
descriptionstringoptional | Optional note on what the group is for. |
tenantIdstringoptional | Tenant to create the group in — only needed when the caller's access spans more than one. Pattern: ^[0-9A-HJ-NP-Za-km-z]{9,16}$ |
Response
| Name | Description |
|---|---|
resourceIdentifierstring | Unique Coldwave resource name (CRN) that identifies a resource |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
List user groups
The groups of the caller's tenant, filtered one by one by read — a principal scoped to single groups still sees those rather than nothing at all.
GET
/api/v1/usergroupResponse
| Name | Description |
|---|---|
namestring | 1 to 64 characters; two groups in a tenant may carry the same name, nothing enforces uniqueness. min length 1 · max length 64 |
descriptionstringoptional | What the group is for; absent when none was given. |
resourceIdentifierstring | Unique Coldwave resource name (CRN) that identifies a resource |
createdBystring | Resource identifier of the entity that created this resource |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
Read a user group
Name and description only. What the group carries and who is in it are separate calls, /roles and /users.
GET
/api/v1/usergroup/Yk3pL7rWq2Path Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|---|
namestring | 1 to 64 characters; two groups in a tenant may carry the same name, nothing enforces uniqueness. min length 1 · max length 64 |
descriptionstringoptional | What the group is for; absent when none was given. |
resourceIdentifierstring | Unique Coldwave resource name (CRN) that identifies a resource |
createdBystring | Resource identifier of the entity that created this resource |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
Update a user group
Writes name and description; a field left out stays as it is. Neither the roles the group carries nor its members are touched here.
PATCH
/api/v1/usergroup/Yk3pL7rWq2Path Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|---|
namestringoptional | 1 to 64 characters; left out, the stored name stays. min length 1 · max length 64 |
descriptionstringoptional | Replaces the stored text; left out it stays as it is, and an empty string is the only way to blank it. |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
Delete a user group
Unlinks the group's roles and its members before removing it, so everyone in it loses what it granted. The roles and the accounts themselves stay.
DELETE
/api/v1/usergroup/Yk3pL7rWq2Path Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
List the group's roles
The CRNs of the roles the group hands to its members. It takes read on the group, not on the roles.
GET
/api/v1/usergroup/Yk3pL7rWq2/rolesPath Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
Add roles to a group
Takes two rights, not one: update on the group and share on every role named — the role reaches everyone already in the group at once.
POST
/api/v1/usergroup/Yk3pL7rWq2/rolesPath Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|---|
| role | One role CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Alternative 1string | Unique Coldwave resource name (CRN) that identifies a resource |
Alternative 2array | One role CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
Remove roles from a group
The same pair of rights as adding, update on the group and share on each role. Members lose the role immediately unless they also hold it directly or through another group.
DELETE
/api/v1/usergroup/Yk3pL7rWq2/rolesPath Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|---|
| role | One role CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Alternative 1string | Unique Coldwave resource name (CRN) that identifies a resource |
Alternative 2array | One role CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
List the group's members
The CRNs of the accounts in the group. It takes read on the group itself, not on each account listed.
GET
/api/v1/usergroup/Yk3pL7rWq2/usersPath Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
Add members to a group
Takes share on the group and read on every account named — deliberately not share on the group's roles, which is what lets a group administrator hand out a bundle they could not have assembled by hand.
POST
/api/v1/usergroup/Yk3pL7rWq2/usersPath Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|---|
| user | One user CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Alternative 1string | Unique Coldwave resource name (CRN) that identifies a resource |
Alternative 2array | One user CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |
Remove members from a group
The same rights as adding a member. Whoever is taken out loses every role the group carried, unless they hold it by another path.
DELETE
/api/v1/usergroup/Yk3pL7rWq2/usersPath Parameters
| Name | Description |
|---|---|
usergroupIdstring | Resource 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
| Name | Description |
|---|---|
| user | One user CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Alternative 1string | Unique Coldwave resource name (CRN) that identifies a resource |
Alternative 2array | One user CRN or a list of them, each in the same tenant as the group; a CRN naming another tenant is refused. |
Errors
| Status | Description | Body |
|---|---|---|
403 | You do not have permission to perform this action | |
404 | No user group with this id exists in the resolved tenant. Check the id, and where the caller's access spans several tenants that X-Tenant-Id names the right one. | |
409 | A tenant with the given name already exists | code: IAM_TENANT_CONFLICT_ERROR |
400 | The request did not match the schema for this endpoint. The details field carries the specific failures. | error: Validation Error |
401 | No valid access token was presented, or the DPoP proof accompanying it was missing, expired or bound to a different key. | error: string |
500 | The request failed for a reason that is not the caller's to fix. Safe to retry. | error: string, message: string, statusCode: 50 |