Skip to content

Dynamic Groups

A dynamic group is a computed collection: a stored definition — a set of seed records plus a traversal spec — whose membership is calculated by walking your reference graph and kept up to date automatically as the underlying relationships change. Membership can then be read directly, filtered against in queries, aggregated on dashboards, or used as a permission grantee exactly like a role or team.

This is how you model “all the configuration items that depend on this database,” “every account under this parent account,” or an org-chart rollup — without maintaining the membership list by hand.

A group’s membership is a governed graph traversal. Starting from the group’s seed records, the platform walks a chosen edge table in a direction and to a depth you specify, and materializes the reachable set into an indexed membership table. The traversal enforces row-level security at every hop — membership is never a raw, unauthorized edge walk.

A dynamic group definition includes:

FieldMeaning
node_tablethe table whose records are members
edge_tablethe reference/relationship table walked to find members
seed_idsthe starting record(s)
viawhich reference/relationship types to follow
directiondownstream, upstream, or both
depthhow many hops to traverse (defaults to 10)
include_seedswhether the seeds themselves count as members

Dynamic groups are app-scoped. Creating, deleting, and recomputing a group requires admin access; reading membership follows normal permissions.

GET /api/apps/{app}/dynamic-groups # list groups
POST /api/apps/{app}/dynamic-groups # create a group
GET /api/apps/{app}/dynamic-groups/{id} # get a group
DELETE /api/apps/{app}/dynamic-groups/{id} # delete a group
GET /api/apps/{app}/dynamic-groups/{id}/members # read materialized membership
POST /api/apps/{app}/dynamic-groups/{id}/recompute # recompute membership on demand

Membership is kept current automatically. When edges in the traversed table change, a background worker recomputes the affected groups (coalesced per group). You can also attach the recompute_dynamic_groups rule action to an edge table’s rules to fan out recomputation, or trigger a synchronous recompute via the /recompute endpoint. Each recompute is a full replace inside a single transaction under a per-group lock, so concurrent recomputes of the same group serialize safely.

A dynamic group can be the target of a permission grant, just like a role or a team:

POST /api/apps/system/tables/permissions/records
{
"grantee_type": "dynamic_group",
"dynamic_group_id": "<group-uuid>",
"resource_type": "table",
"resource_name": "changes",
"application": "itsm",
"grants": { "operations": ["read"] }
}

Grants to a role, a team, and a dynamic group all resolve through the same grant path and priority ladder. A user’s effective access is the union (most-permissive wins) of the grants on every role they hold, every team they belong to, and every dynamic group they are a member of. See Permissions for the full priority model.