Groups and RBAC
Groups are the primary unit of access control in Arbitex. They collect users, define which AI models those users can reach, and carry per-group DLP detector overrides. All group management endpoints require the admin role and operate under the /api/admin/groups router prefix.
Overview
Section titled “Overview”Groups model
Section titled “Groups model”A group has a name (unique within the tenant), an optional description, and an optional link to an Azure Entra AD group via entra_ad_group_id. Groups are tenant-scoped — a group created in one tenant is not visible to another.
Each group stores:
| Field | Type | Notes |
|---|---|---|
id | UUID | System-generated |
name | string (255) | Unique per tenant |
description | string (1000) | Optional |
entra_ad_group_id | string (255) | Optional — maps to an Azure AD group for SCIM sync |
created_at | timestamp | Set on creation |
updated_at | timestamp | Updated on any change |
Arbitex has two platform-level roles:
| Role | Capabilities |
|---|---|
ADMIN | Full access to all admin endpoints including group CRUD, membership, model access, DLP config, and org-level defaults |
USER | No access to admin endpoints; subject to group membership and model access rules |
Group membership does not itself confer elevated role permissions. Roles are assigned directly to user accounts. Groups govern model access and DLP policy, not platform role.
Permission inheritance chain
Section titled “Permission inheritance chain”Model access is resolved in this order:
- Org defaults —
GET /api/admin/model-access/org-defaults— apply to all users in the organization. - Group overrides —
GET /api/admin/groups/{group_id}/model-access— override org defaults for members of that group. - Effective access — the result after applying applicable group rules on top of org defaults.
When a user belongs to multiple groups, the most permissive allow rule wins unless an explicit deny applies. Group rules always take precedence over org defaults when a rule exists for the model.
Creating and managing groups
Section titled “Creating and managing groups”Create a group
Section titled “Create a group”curl -X POST https://api.arbitex.ai/api/admin/groups \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "ml-engineers", "description": "Machine learning engineering team", "entra_ad_group_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }'Request body:
| Field | Required | Notes |
|---|---|---|
name | Yes | Must be unique within the tenant. Returns 409 if the name already exists. |
description | No | Free-text description |
entra_ad_group_id | No | Azure AD object ID for SCIM group sync |
Response:
{ "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "name": "ml-engineers", "description": "Machine learning engineering team", "entra_ad_group_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "created_at": "2026-03-09T00:00:00Z", "updated_at": "2026-03-09T00:00:00Z"}List all groups
Section titled “List all groups”curl https://api.arbitex.ai/api/admin/groups \ -H "Authorization: Bearer $ADMIN_TOKEN"Response:
{ "items": [ { "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "name": "ml-engineers", "description": "Machine learning engineering team", "member_count": 12, "entra_ad_group_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "created_at": "2026-03-09T00:00:00Z", "updated_at": "2026-03-09T00:00:00Z" } ], "total": 1}The member_count field is included in both list and single-group responses.
Get a single group
Section titled “Get a single group”curl https://api.arbitex.ai/api/admin/groups/{group_id} \ -H "Authorization: Bearer $ADMIN_TOKEN"Update a group
Section titled “Update a group”PUT performs a partial update — only fields provided in the body are changed.
curl -X PUT https://api.arbitex.ai/api/admin/groups/{group_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "description": "Updated description for ML engineers" }'Any combination of name, description, and entra_ad_group_id may be included. Omitted fields are left unchanged.
Delete a group
Section titled “Delete a group”curl -X DELETE https://api.arbitex.ai/api/admin/groups/{group_id} \ -H "Authorization: Bearer $ADMIN_TOKEN"Deleting a group removes the group record, all membership associations, and all DLP config overrides for that group. Model access rules scoped to the group are also removed. This operation is not reversible.
Managing group membership
Section titled “Managing group membership”List members
Section titled “List members”curl https://api.arbitex.ai/api/admin/groups/{group_id}/members \ -H "Authorization: Bearer $ADMIN_TOKEN"Response includes user details for each member:
[ { "id": "11111111-2222-3333-4444-555555555555", "username": "alice", "email": "alice@example.com" }]Add a member
Section titled “Add a member”curl -X POST https://api.arbitex.ai/api/admin/groups/{group_id}/members \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "user_id": "11111111-2222-3333-4444-555555555555" }'The user_id must be a valid UUID string referencing an existing user. Returns 409 if the user is already a member of the group.
Remove a member
Section titled “Remove a member”curl -X DELETE https://api.arbitex.ai/api/admin/groups/{group_id}/members/{user_id} \ -H "Authorization: Bearer $ADMIN_TOKEN"Removing a user from a group takes effect immediately. The user’s effective model access reverts to org defaults for any models that were governed solely by the group rule.
Model access control
Section titled “Model access control”Model access rules control which AI models the members of a group can use. Rules are set per group per model, and use an access_type of either allow or deny.
Per-group model access
Section titled “Per-group model access”List access rules for a group
Section titled “List access rules for a group”curl https://api.arbitex.ai/api/admin/groups/{group_id}/model-access \ -H "Authorization: Bearer $ADMIN_TOKEN"Response:
[ { "model_id": "gpt-4o", "provider": "openai", "access_type": "allow" }, { "model_id": "claude-opus-4-6", "provider": "anthropic", "access_type": "deny" }]Set a model access rule
Section titled “Set a model access rule”This endpoint upserts — if a rule already exists for the given model_id, it is updated in place.
curl -X POST https://api.arbitex.ai/api/admin/groups/{group_id}/model-access \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "model_id": "gpt-4o", "provider": "openai", "access_type": "allow" }'Request body:
| Field | Required | Notes |
|---|---|---|
model_id | Yes | Model identifier string (e.g., gpt-4o) |
provider | Yes | Provider name (e.g., openai, anthropic) |
access_type | Yes | allow or deny |
Remove a model access rule
Section titled “Remove a model access rule”curl -X DELETE https://api.arbitex.ai/api/admin/groups/{group_id}/model-access/{model_id} \ -H "Authorization: Bearer $ADMIN_TOKEN"After removal, the org-level default for that model applies to group members.
Org-level model access defaults
Section titled “Org-level model access defaults”Org defaults establish the baseline access for all users before group rules are applied.
List org defaults
Section titled “List org defaults”curl https://api.arbitex.ai/api/admin/model-access/org-defaults \ -H "Authorization: Bearer $ADMIN_TOKEN"Set an org default
Section titled “Set an org default”curl -X POST https://api.arbitex.ai/api/admin/model-access/org-defaults \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "model_id": "gpt-4o-mini", "provider": "openai", "access_type": "allow" }'Remove an org default
Section titled “Remove an org default”curl -X DELETE https://api.arbitex.ai/api/admin/model-access/org-defaults/{model_id} \ -H "Authorization: Bearer $ADMIN_TOKEN"Permission inheritance
Section titled “Permission inheritance”The following matrix shows the effective access result for a given model, given an org-level default and a group-level override for a user who is a member of that group.
| Org default | Group override | Effective access |
|---|---|---|
allow | allow | allow |
allow | deny | deny |
allow | (no rule) | allow |
deny | allow | allow |
deny | deny | deny |
deny | (no rule) | deny |
| (no rule) | allow | allow |
| (no rule) | deny | deny |
| (no rule) | (no rule) | deny (default-closed) |
When no rule exists at either level, access is denied by default. To grant access to a model organization-wide, set an org-level allow default. To restrict a model for a specific group while it is allowed org-wide, set a group-level deny override for that group.
Group DLP configuration
Section titled “Group DLP configuration”Each group can carry DLP detector overrides that change how detection events are handled for members of that group. These overrides apply in addition to the platform-level DLP policy.
GroupDLPAction values
Section titled “GroupDLPAction values”| Value | Behavior |
|---|---|
SKIP | Bypass this detector entirely for the group — no detection is performed |
BLOCK | Block the request when this detector fires |
CANCEL | Cancel the request and prompt the user to revise their input |
REDACT | Redact the matched content before the prompt is forwarded to the model |
List DLP overrides for a group
Section titled “List DLP overrides for a group”curl https://api.arbitex.ai/api/admin/groups/{group_id}/dlp \ -H "Authorization: Bearer $ADMIN_TOKEN"Response:
[ { "detector_name": "pii-ner", "action": "REDACT", "enabled": true }, { "detector_name": "secrets-regex", "action": "BLOCK", "enabled": true }]Replace DLP config for a group
Section titled “Replace DLP config for a group”PUT performs a full replacement of the group’s DLP config. The entire list is replaced — any detectors not included in the request body are removed from the group’s config.
curl -X PUT https://api.arbitex.ai/api/admin/groups/{group_id}/dlp \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '[ { "detector_name": "pii-ner", "action": "REDACT", "enabled": true }, { "detector_name": "secrets-regex", "action": "BLOCK", "enabled": true }, { "detector_name": "financial-gliner", "action": "SKIP", "enabled": true } ]'To clear all DLP overrides for a group, PUT an empty array:
curl -X PUT https://api.arbitex.ai/api/admin/groups/{group_id}/dlp \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '[]'Entra AD group sync
Section titled “Entra AD group sync”Groups support an entra_ad_group_id field that maps the Arbitex group to an Azure Entra ID group object. This mapping is used by the SCIM provisioning connector to maintain membership automatically.
When SCIM sync is active, the connector pushes group membership changes from Entra ID to Arbitex. Adding or removing a user from the linked Entra AD group propagates to the Arbitex group membership without manual API calls.
Setting the Entra AD group ID
Section titled “Setting the Entra AD group ID”The entra_ad_group_id can be set at group creation or updated via PUT:
# At creationcurl -X POST https://api.arbitex.ai/api/admin/groups \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "data-science", "entra_ad_group_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }'
# Or added to an existing groupcurl -X PUT https://api.arbitex.ai/api/admin/groups/{group_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "entra_ad_group_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }'The entra_ad_group_id value is the Object ID of the group in Azure Entra ID, visible in the Azure Portal under Microsoft Entra ID → Groups → the target group → Overview.
Removing the Entra AD link
Section titled “Removing the Entra AD link”To unlink a group from Entra ID without deleting the group, set entra_ad_group_id to null:
curl -X PUT https://api.arbitex.ai/api/admin/groups/{group_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "entra_ad_group_id": null }'After unlinking, membership changes in Entra ID no longer propagate to this group. Existing memberships in Arbitex are not modified by the unlink operation.
See also
Section titled “See also”- Entra ID SCIM provisioning — Automate user and group sync from Entra ID
- Entra ID SSO — Configure OIDC single sign-on with Microsoft Entra ID
- DLP policy guide — Platform-level DLP configuration and detector reference
- Model access API reference — Full API reference for model access endpoints