Skip to main content

Groups Endpoint

The /Groups endpoint manages SCIM Group resources for organizing users. SCIM (System for Cross-domain Identity Management) is the standard for syncing users and groups between systems. The resource shape comes from the SCIM 2.0 core schema, and the HTTP verbs and PATCH operations come from the SCIM 2.0 protocol.

In LumoAuth a SCIM Group is an organization role: adding a member grants that role, removing a member revokes it. Two rules follow from that:

  • Every write on /Groups is refused with 403 when the organization has switched off Allow group operations (see provisioning policy).
  • Roles that make their members administrators can never be managed through SCIM (see Protected roles).

Every example uses the organization's SCIM provisioning token ($SCIM_TOKEN).

List Groups​

GET /orgs/\{orgId\}/api/v1/scim2.0/Groups

curl -X GET "https://app.lumoauth.dev/orgs/acme-corp/api/v1/scim2.0/Groups" \
-H "Authorization: Bearer $SCIM_TOKEN" \
-H "Accept: application/scim+json"

Filtering​

GET /Groups?filter=... accepts exactly one of these forms; anything else, including and / or combinations, returns 400 invalidFilter:

FilterMatches
displayName eq "Engineering" (also co, sw)Groups by name
externalId eq "okta-00g1"The group created with that externalId
id eq "10"One group by id
members[value eq "123"]Groups that user 123 belongs to

POST /Groups/.search uses the general filter grammar over id, externalId, displayName, meta.created, meta.lastModified and isSoftDeleted.

Response​

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 5,
"Resources": [
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"id": "10",
"displayName": "Engineering",
"members": [
{"value": "123", "$ref": ".../Users/123", "display": "John Smith"},
{"value": "456", "$ref": ".../Users/456", "display": "Jane Doe"}
],
"meta": {
"resourceType": "Group",
"created": "2024-01-01T00:00:00Z",
"lastModified": "2024-06-15T12:30:00Z",
"location": "https://app.lumoauth.dev/orgs/acme-corp/api/v1/scim2.0/Groups/10",
"version": "W/\"3\""
}
}
]
}

Create Group​

POST /orgs/\{orgId\}/api/v1/scim2.0/Groups

curl -X POST "https://app.lumoauth.dev/orgs/acme-corp/api/v1/scim2.0/Groups" \
-H "Authorization: Bearer $SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Marketing",
"members": [
{"value": "123"},
{"value": "456"}
]
}'

Update Group Members (PATCH)​

Use PATCH to add or remove members without replacing the entire group:

# Add members
curl -X PATCH "https://app.lumoauth.dev/orgs/acme-corp/api/v1/scim2.0/Groups/10" \
-H "Authorization: Bearer $SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{"op": "add", "path": "members", "value": [{"value": "789"}]}
]
}'

# Remove specific member
curl -X PATCH "https://app.lumoauth.dev/orgs/acme-corp/api/v1/scim2.0/Groups/10" \
-H "Authorization: Bearer $SCIM_TOKEN" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{"op": "remove", "path": "members[value eq \"123\"]"}
]
}'

Delete Group​

DELETE /orgs/\{orgId\}/api/v1/scim2.0/Groups/\{id\}

Deleting a group removes every member from the role and then deletes the role. There is no soft delete for groups. System and privileged roles cannot be deleted (403, see below).

Protected roles​

SCIM group membership can never hand out administrator authority. A group is refused for PUT, PATCH and DELETE when the underlying role is a system role (for example the built-in organization administrator role) or when it confers administrator authority. A role confers administrator authority when it holds at least one permission that lets its members change who can do what in the organization. The families are:

FamilyPermissions counted as administrative
Organization settingssettings.create, settings.edit, settings.delete, settings.manage
Users, roles, groupsusers.create, users.edit, users.delete, roles.create, roles.edit, roles.delete, roles.assign-permissions, groups.create, groups.edit, groups.delete
Customer organizationsorganizations.members.manage, organizations.invitations.manage
Identity providers and provisioningidps.create, idps.edit, idps.delete, scim.create, scim.edit, scim.delete, scim.manage
Signing keyssigning_keys.create, signing_keys.edit, signing_keys.rotate, signing_keys.revoke, signing_keys.delete
OAuth clientsclients.create, clients.edit, clients.delete, clients.rotate-secret
AI agents, policies, approvalsagents.create, agents.edit, agents.delete, policies.create, policies.edit, policies.delete, jit.approve
Fine-grained authorizationzanzibar.create, zanzibar.edit, zanzibar.delete, abac.manage
Privacy and billinggdpr.manage, gdpr.dpo, billing.manage
Platformtenants.create, tenants.edit, tenants.delete

Read-only permissions (*.view, audit.*, analytics.*, webhooks.*, branding.*) do not make a role administrative, so groups for ordinary job functions work as expected.

The refusal is a SCIM error:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"status": "403",
"scimType": "mutability",
"detail": "System or privileged roles cannot be modified via SCIM"
}

(... cannot be deleted via SCIM for DELETE.) Creating a group whose name maps to a reserved slug such as admin is refused with 400 invalidValue. Administrators are assigned in the portal or the Admin API, where the same no privilege gain rule applies.

Common mistakes​

  • Okta "Push Groups" fails with 403 for one group only. That group maps to a role holding an administrative permission (table above). Keep administrators out of IdP-managed groups, or split the role.
  • Every group push fails with 403. Allow group operations is off at /orgs/{orgId}/portal/integrations/scim.
  • 400 invalidFilter when looking a group up. Only the forms in Filtering are supported on GET /Groups; an unsupported filter is rejected instead of returning every group.
  • 400 invalidValue on create. The display name converts to a reserved slug (admin, and similar). Rename the group in the IdP.

Group Schema​

AttributeTypeRequiredDescription
idstring-Unique identifier (readOnly)
displayNamestringYesGroup display name
externalIdstringNoExternal system identifier
membersarrayNoGroup membership (User references)
metaobject-Resource metadata (readOnly)

Standards used on this page​

Plain nameStandard
SCIM 2.0 (user and group provisioning)RFC 7642, RFC 7643 and RFC 7644

See the standards reference for what each one covers and how LumoAuth uses it.