Skip to content

Groups

Partial

A group is a named set of entities cutting across the structural trees: the tree handles config by position and kind, groups by attribute or hand-picked set (“all AV displays”). One primitive serves two jobs, a cascade overlay and an access scope, which an anonymous predicate never could.

What is built is the principal arm: principal_group and its membership, a grant subject (grants attach to the group and reach its members), not an access scope (scope_kind='group' is refused today with a 422).

A group’s name is an ordinary entity name (^[a-z0-9][a-z0-9-]*$, 100 characters, a uuid refused), enforced by the Storage Gateway on create and on rename rather than by the request schema alone (ADR-0077). Moving it is the :rename custom method, POST /principal-groups/{id}:rename gated by principal_group:rename; the PATCH body does not carry a name at all (ADR-0076). The whole collection is addressed by the uuid, so a group is the one case where the rename route takes an {id} rather than the name it is about to move; nothing inside the platform notices, since membership and grants both key on that uuid.

principal_group (identity): generated from the migrated schema by make gen
Column Type Constraints
id uuid PK, default uuidv7()
name text not null
label text
description text
created_at timestamp with time zone not null, default now()
updated_at timestamp with time zone not null, default now()
CHECK constraints and unique indexes on principal_group
  • principal_group_name_key: CREATE UNIQUE INDEX principal_group_name_key ON public.principal_group USING btree (name)
principal_group_member (identity): generated from the migrated schema by make gen
Column Type Constraints
group_id uuid PK, FK → principal_group.id
principal_id uuid PK, FK → principal.id
created_at timestamp with time zone not null, default now()