User Groups
Groups allow you to organize users and include group membership information in access tokens and userinfo responses. Groups are managed via the admin API and can be used for role-based access control in your applications.
Groups in tokens
Section titled “Groups in tokens”When the groups scope is requested and granted, the user’s group names are included as a groups claim in:
- Access tokens – as an array of group name strings
- ID tokens – as an array of group name strings
- Userinfo responses – as a
groupsfield
Example token claims:
{ "sub": "user-123", "groups": ["admins", "developers", "team-alpha"], "scope": "openid profile groups"}Custom claims inherited by members
Section titled “Custom claims inherited by members”In Admin → Groups, choose Manage claims to add, replace, or remove a
custom string claim. Members receive each claim under a literal
group.claim key when the custom_claims scope is granted. For example,
role=user on group app1 produces:
{ "app1.role": "user" }Group app2 can independently define role=editor, producing app2.role.
These are top-level keys, not nested objects. An individual claim named
app1.role overrides that inherited value. An administrator can also assign
that individual claim without adding the user to app1.
Group-local names may include role, email, or sub: they are always prefixed
and cannot replace Autentico’s built-in claims. Names follow the existing bare
custom-claim pattern and are limited to 128 characters; values are strings of up
to 4096 characters, including empty strings.
The custom_claims scope controls inherited custom claims independently of the
groups scope. See Custom Claims for individual overrides.
Admin API endpoints
Section titled “Admin API endpoints”All group endpoints require admin authentication.
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/api/groups |
List all groups (paginated) |
POST |
/admin/api/groups |
Create a new group |
GET |
/admin/api/groups/{id} |
Get a group by ID |
PUT |
/admin/api/groups/{id} |
Update a group |
DELETE |
/admin/api/groups/{id} |
Delete a group |
GET |
/admin/api/groups/{id}/members |
List members of a group |
POST |
/admin/api/groups/{id}/members |
Add a user to a group |
DELETE |
/admin/api/groups/{id}/members/{user_id} |
Remove a user from a group |
GET |
/admin/api/groups/{id}/claims |
List group-local custom claims |
POST |
/admin/api/groups/{id}/claims |
Create or update a group-local claim |
DELETE |
/admin/api/groups/{id}/claims/{name...} |
Remove a group-local claim |
GET |
/admin/api/users/{id}/groups |
Get groups for a specific user |
List groups
Section titled “List groups”curl https://auth.example.com/admin/api/groups \ -H "Authorization: Bearer $ADMIN_TOKEN"Supports query parameters:
| Parameter | Description |
|---|---|
sort |
Sort field: name, created_at, updated_at |
order |
Sort order: asc (default), desc |
search |
Search across name and description |
limit |
Max results per page (1–100, default 100) |
offset |
Number of results to skip (default 0) |
Response:
{ "items": [ { "id": "cq1abc123", "name": "developers", "description": "Engineering team", "member_count": 5, "created_at": "2026-01-15T10:00:00Z", "updated_at": "2026-01-15T10:00:00Z" } ], "total": 1}Create a group
Section titled “Create a group”curl -X POST https://auth.example.com/admin/api/groups \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "developers", "description": "Engineering team"}'| Field | Required | Validation |
|---|---|---|
name |
Yes | 1–100 characters, alphanumeric plus - and _ only |
description |
No | Up to 500 characters |
Group names must be unique. Attempting to create a group with a duplicate name returns a 409 Conflict error.
Add a user to a group
Section titled “Add a user to a group”curl -X POST https://auth.example.com/admin/api/groups/$GROUP_ID/members \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"user_id": "user-123"}'Returns 201 Created on success. Returns 409 Conflict if the user is already a member.
Remove a user from a group
Section titled “Remove a user from a group”curl -X DELETE https://auth.example.com/admin/api/groups/$GROUP_ID/members/$USER_ID \ -H "Authorization: Bearer $ADMIN_TOKEN"Get groups for a user
Section titled “Get groups for a user”curl https://auth.example.com/admin/api/users/$USER_ID/groups \ -H "Authorization: Bearer $ADMIN_TOKEN"Manage group claims
Section titled “Manage group claims”curl -X POST https://auth.example.com/admin/api/groups/$GROUP_ID/claims \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"role","value":"user"}'Posting an existing local name replaces its value. Lists return the local name
(role), string value, and update timestamp in the same data envelope as user
claims. Deletion uses the local name; percent-encode names containing slashes.
Unknown groups return 404 on list/upsert; missing claims return 404 on deletion.
Database tables
Section titled “Database tables”groups table
Section titled “groups table”| Column | Type | Description |
|---|---|---|
id |
TEXT | Primary key (xid) |
name |
TEXT | Unique group name |
description |
TEXT | Optional description |
created_at |
DATETIME | Creation timestamp |
updated_at |
DATETIME | Last update timestamp |
user_groups table
Section titled “user_groups table”| Column | Type | Description |
|---|---|---|
user_id |
TEXT | Foreign key to users.id |
group_id |
TEXT | Foreign key to groups.id |
created_at |
DATETIME | When the membership was created |
A unique constraint on (user_id, group_id) prevents duplicate memberships. Deleting a group cascades to remove all memberships.
group_claims table
Section titled “group_claims table”Migration 23 adds group_id, claim_name, claim_value, created_at, and
updated_at. The primary key is (group_id, claim_name). Deleting a group
cascades to its claims. Inherited values are resolved through membership rather
than copied into user_claims.