Groups

Groups add structure inside an organization. They form a tree, and membership is recursive: a member of a group is effectively a member of every group above it, and inherits the roles mapped to each of them.

That is what makes “everyone in Engineering can read the build logs, and the Platform sub-team can also deploy” expressible without assigning roles user by user.

The group tree

A group belongs to one organization and points at a parent through parent_group_id. A null parent means the group sits at the top level.

Acme Corp (organization)
└── Engineering              roles: build:read
    ├── Platform             roles: deploy
    └── Frontend

A user added to Platform is a member of Platform and of Engineering, and holds both deploy and build:read.

Group fields

FieldTypeDescription
idUUID v7Identifier
organization_idUUIDThe organization the group belongs to
parent_group_idUUID or nullParent group. null for a top-level group
nameStringGroup name, required
descriptionStringFree-text description
created_atDateTime (UTC)Creation timestamp
updated_atDateTime (UTC)Last-modified timestamp

Updating a group can move it: sending a new parent_group_id reparents it, and sending null promotes it to the top level.

Endpoints

All of them are scoped to a realm and an organization.

Groups

MethodEndpointDescription
GET/realms/{realm_name}/organizations/{organization_id}/groupsList the organization’s groups
POST/realms/{realm_name}/organizations/{organization_id}/groupsCreate a group
GET/realms/{realm_name}/organizations/{organization_id}/groups/{group_id}Read one group
PUT/realms/{realm_name}/organizations/{organization_id}/groups/{group_id}Update or reparent a group
DELETE/realms/{realm_name}/organizations/{organization_id}/groups/{group_id}Delete a group

Listing returns the tree: each node carries the group’s own fields plus a children array of the same shape.

Members

MethodEndpointDescription
GET.../groups/{group_id}/membersList the group’s members, paginated
POST.../groups/{group_id}/membersAdd a user to the group
DELETE.../groups/{group_id}/members/{user_id}Remove a user from the group

The member list is enriched, so a client can render it without walking the user directory. Each entry carries username, email, firstname, lastname, and enabled alongside the membership ids, and the response wraps them with total, limit, and offset for server-side pagination.

Roles

MethodEndpointDescription
GET.../groups/{group_id}/rolesList the roles mapped to the group
POST.../groups/{group_id}/rolesMap a role to the group
DELETE.../groups/{group_id}/roles/{role_id}Unmap a role

Every member of the group, and of every group below it, inherits the roles mapped here.

Attributes

MethodEndpointDescription
GET.../groups/{group_id}/attributesList the group’s attributes
PUT.../groups/{group_id}/attributes/{key}Upsert an attribute
DELETE.../groups/{group_id}/attributes/{key}Delete an attribute

Same key-value shape and same upsert behaviour as organization attributes.

Permissions

Groups use the same realm-level gates as the rest of the organization module: ManageRealm or ManageUsers to write, and ViewUsers on top of those to read. There are no group-specific permissions.