Groups Role Restriction
Group Role Restriction controls who can log in to an application by verifying group membership and roles during authentication. When verification succeeds, selected hints embed the matching groups and roles into the JWT access token so your application can see why access was granted — without loading every group the user belongs to.
You are in the right place if you want to:
- Understand what Group Role Restriction is — the problem it solves, how it works at login, and how to configure it
- Show why a user got access in the token — configure hints on the app and read the resulting JWT claims
- Validate access at runtime — call the verification APIs when permissions may have changed since login
- Manage persistent verification requests — store and reuse verification rules via CRUD APIs
For broader context, see Permission Management and User Groups and Roles.
1. What is Group Role Restriction?
Users often belong to multiple groups with different roles in each. Without restriction, a login token can include all of a user's roles — even those irrelevant to the application. That leads to oversized tokens, unnecessary exposure of permissions, and confusing authorization logic.
Example: Mark belongs to three groups:
| Group | Group ID | Roles |
|---|---|---|
| Engineering Team | eng-group | developer, code-reviewer |
| Support Team | support-group | support-agent |
| HR Team | hr-group | hr-viewer |
When Mark logs into the HR Portal, only hr-viewer from hr-group is relevant. Group Role Restriction ensures the HR Portal token contains only that role — not his engineering or support roles.
| Without restriction | With restriction |
|---|---|
| Token includes all roles from all groups | Token includes only roles from matched groups |
| Risk of "Header Too Large" errors | Smaller, application-specific token |
| App sees permissions it does not need | App sees only what the restriction allows |
When verification runs
- At login (primary): cidaas evaluates the app's group role restriction as a Token Condition (
group_validation). If verification fails, login is blocked. If it succeeds, configured hints add claims to the JWT (see Section 2). - At runtime (optional): your application can call the verification APIs for live checks when permissions may have changed since the token was issued.
Configure group role restriction
On each application, define filters (which groups and roles are required), a matchCondition (and or or), and hints (which matched groups/roles are added to the JWT). Users who do not meet the restriction cannot log in to that application.
| Where | Trustdesk (4.x) | Admin Dashboard (legacy) |
|---|---|---|
| Per-app login restriction | Integrations → Applications → select application → group and role restrictions | Apps → App Settings → Advanced Settings → Group and role restrictions |
| Persistent verification rules (runtime reuse) | Permission Setup → User Group Verification Filter | — |
You can also configure groupRoleRestriction via the App Settings API (groupRoleRestriction object).
For Trustdesk navigation and the Admin Dashboard → Trustdesk mapping, see Introducing Trustdesk.
Core concepts
| Term | Meaning |
|---|---|
| Filter | Match criteria: exactly one of groupId or groupType per filter, optionally with roleFilter |
| matchCondition | "and" — user must satisfy all filters; "or" — user must satisfy at least one filter |
| GVR | Group Verification Request — verification rules, either stored for reuse by id or sent transiently in an API call |
| Hint | Controls which group/role data is returned — in JWT claims at login, or in the API response at runtime |
How it works
┌─────────────────────────────────────────────────────────────────┐
│ GROUP ROLE RESTRICTION MODEL │
├─────────────────────────────────────────────────────────────────┤
│ │
│ User ──member of──► UserGroup ──has──► Roles │
│ │ │
│ │ verified at login │
│ ▼ │
│ App groupRoleRestriction (filters + matchCondition + hints) │
│ │ │
│ ├── verified: false ──► login blocked │
│ └── verified: true ──► hints ──► JWT claims │
│ │
└─────────────────────────────────────────────────────────────────┘
Key relationships:
- User → UserGroup → Roles: cidaas stores group memberships and per-group roles for each user
- App restriction → Login: the app's
groupRoleRestrictiondefines what must match before access is granted - Hints → Token: on success, hints control which matched groups/roles appear as JWT claims
Benefits
- Smaller tokens — only application-relevant groups and roles are included
- Stronger security — users without the required group/role cannot log in; tokens do not leak unrelated permissions
- Simpler authorization — applications read flat role lists from the token instead of querying group membership on every request
Related: Learn how this fits into the authentication flow in Token Conditions and Prechecks.
2. Why the user got access: hints in the token
When verification succeeds at login, hints on the app's groupRoleRestriction determine which group and role information is embedded in the JWT. This is how your application can see which group and role satisfied the restriction — not just that login was allowed.
Note: Hints on the app configuration affect JWT claims at login only. For API response fields at runtime, see Section 3.
Hint values
| Hint | JWT claim | Best for |
|---|---|---|
default (or omitted) | None — verification only, no extra claims | Login gate only; no role data needed in token |
groupIds | groupIds[] | Knowing which groups matched |
rolesOfGroup | rolesOfGroup[] | Flat role checks (most common) |
allowedGroups | allowedGroups[{groupId, roles}] | Full audit trail — group and role per match |
You can combine multiple hints to add different claim types to the same token. Configure hints on the application's group role restriction in Integrations → Applications (Trustdesk) or via the App Settings API (groupRoleRestriction.hints).
Example: HR Portal
| Setting | Value |
|---|---|
| Filter | groupId: hr-group, roles hr-viewer or hr-admin |
| matchCondition | or |
| hints | allowedGroups, rolesOfGroup |
When Mark logs in, cidaas verifies he is in hr-group with hr-viewer. His token contains only HR-relevant claims:
| Claim | Value |
|---|---|
rolesOfGroup | ["hr-viewer"] |
allowedGroups | [{ groupId: "hr-group", roles: ["hr-viewer"] }] |
The allowedGroups claim shows which group granted access and which role within it. The rolesOfGroup claim provides a flat list for simple permission checks.
Login-time match behavior
Note: Match behavior differs between login-time token claims and runtime API responses (see Section 3).
"or": Processing stops at the first matching filter. Only groups and roles from that filter are added to the token — keeping the payload small."and": The user must satisfy all filters. Claims include groups and roles from every satisfied filter (roles are deduplicated).
For detailed OR/AND configuration examples, see Match Conditions Reference in the integration guide.
Using claims in your application
After login, read rolesOfGroup, groupIds, or allowedGroups from the verified JWT access token. Always validate the token signature before trusting claims. Map roles to application permissions rather than checking role names directly.
For framework-specific examples (Spring Security, Django, OPA, and more), see Group Role Restrictions — Integration Examples.
3. Real-time validation in your application
Use the verification APIs when you need to check group membership and roles after login — for example before a sensitive operation or when permissions may have changed since the token was issued.
When to use JWT claims vs the API
| Approach | When | Data source |
|---|---|---|
| JWT hints (Section 2) | After login; fast offline checks | Token claims |
| Verification APIs (this section) | Before a sensitive action; permissions may have changed | Live API response |
Verification endpoints
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /groups-srv/verifications | Transient check — send sub, matchCondition, filters, and optional hints inline |
| GET | /groups-srv/verifications/{verificationId}?sub={userId} | Reuse a stored verification request by id |
API references:
Request fields
| Field | POST | GET |
|---|---|---|
sub | Required in request body | Required as query parameter |
matchCondition | Required in request body | Loaded from stored request |
filters | Required in request body | Loaded from stored request |
hints | Optional in request body — controls response fields | Loaded from stored request |
Each filter must specify exactly one of groupId or groupType (not both, not neither). When roleFilter is provided, include matchCondition and at least one role in roles. A roleFilter can be used with either groupId or groupType.
Hints in API responses
Optional hints on POST (or stored on a persistent GVR for GET) control which fields appear in the API response:
| Hint | Response field |
|---|---|
default (or omitted) | verified only |
groupIds | data.groupIds[] |
rolesOfGroup | data.rolesOfGroup[] |
allowedGroups | data.allowedGroups[{groupId, roles}] |
Authentication requirements
| Rule | POST /verifications | GET /verifications/{verificationId} |
|---|---|---|
| Bearer token | Required | Required |
| Anonymous token | Requires cidaas:users_read scope | Requires cidaas:users_read scope |
| Non-admin user | Any valid sub in body | sub query param must match token sub |
| Admin user | Any valid sub in body | Can verify any user |
Response fields
| Field | Meaning |
|---|---|
data.verified | true if the user meets the restriction; use as allow/deny decision |
data.allowedGroups | Groups that matched, with roles per group — explains why access was granted |
data.groupIds | Flat list of matching group IDs (when groupIds hint is set) |
data.rolesOfGroup | Flat list of matching roles (when rolesOfGroup hint is set) |
When data.verified is false, allowedGroups is empty.
Note: For API responses, when a user matches multiple groups, all matching groups can appear in
allowedGroups. This differs from login-time token claims with"or", where only the first matching filter is included.
For request/response examples and integration code, see Group Role Restrictions — Integration Examples.
4. Manage persistent verification requests
Persistent Group Verification Requests (GVR) store verification rules under a reusable id. Create them once via CRUD APIs, then verify users with GET /groups-srv/verifications/{verificationId}?sub=.
Use persistent GVRs when the same rules apply across multiple services, when you want centralized rule management separate from app settings, or when you need to update verification logic without changing each app's configuration.
CRUD endpoints
| Method | Endpoint | Description | API reference |
|---|---|---|---|
| POST | /groups-srv/verifications/requests | Create a new GVR | Create |
| PUT | /groups-srv/verifications/requests/{id} | Update an existing GVR | Update |
| GET | /groups-srv/verifications/requests/{id} | Retrieve a GVR by id | Get by ID |
| DELETE | /groups-srv/verifications/requests/{id} | Delete a GVR | Delete |
| POST | /groups-srv/graph/verifications/requests | Search GVRs with graph filter | Find |
After creating a GVR, verify users with GET /groups-srv/verifications/{verificationId}?sub=.
Authentication requirements
CRUD operations require the appropriate OAuth scope and membership in CIDAAS_ADMINS with an authorized role:
| Operation | Scope | Authorized roles (in CIDAAS_ADMINS) |
|---|---|---|
| Create | cidaas:groups_write | ADMIN, SECONDARY_ADMIN, GROUPFILTER_MANAGER, GROUP_MANAGER, GROUPSETUP_MANAGER |
| Update | cidaas:groups_write | Same as Create |
| Read / Find | cidaas:groups_read | Above plus GROUPFILTER_VIEWER, GROUP_VIEWER |
| Delete | cidaas:groups_delete | ADMIN, SECONDARY_ADMIN, GROUPFILTER_MANAGER, GROUP_MANAGER, GROUPSETUP_MANAGER |
Runtime verification endpoints (POST and GET verify) require a Bearer token but do not require admin roles.
Create and update rules
| Rule | Detail |
|---|---|
id | Required on create. Alphanumeric characters, underscores, and hyphens only (^[a-zA-Z0-9_-]+$). Stored lowercase. |
Duplicate id | Returns 409 Conflict — use PUT to update an existing request |
matchCondition | Required — "and" or "or" |
filters | Required — at least one filter; each filter must have exactly one of groupId or groupType |
hints | Optional — controls response fields when verifying via GET |
sub | Omit on create/update — supplied at verification time via GET query parameter or POST body |
Updatable fields on PUT: matchCondition, filters, and hints. The path {id} must match the id in the request body.
App configuration vs persistent GVR
App groupRoleRestriction | Persistent GVR | |
|---|---|---|
| Purpose | Restrict login to an application | Reusable rules for runtime verification |
| Configured via | Trustdesk / App Settings API | CRUD APIs |
| Hints affect | JWT access token at login | API response on GET verify |
| User interaction | Blocks login if verification fails | Returns verified: true/false |
Related documentation
- Group Role Restrictions — Integration Examples — framework examples, match conditions, usage scenarios, and code samples
- Token Conditions and Prechecks — how
group_validationfits into authentication - Groups and Roles API — full API reference
Please contact us directly on our support page or reach out to cidaas support at [email protected].