User Groups
Groups provide team-level role assignment — add users to a group and all group members inherit the group's roles and resource policy assignments, simplifying access management at scale.
Groups vs. Roles
Groups are organizational — they represent teams, departments, or functional units. Roles are capability definitions — they define what permissions a user has. The connection: groups are assigned roles, and users are assigned to groups.
// Hierarchy:
User → Group → Role → Permission Set → Permission Strings
User → Role → Permission Set → Permission Strings (direct role assignment)
Creating a Group
POST /passport/admin/groups
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"groupName": "finance-team",
"displayName": "Finance Team",
"description": "Accounts, payroll, and financial reporting staff",
"tenantId": "tenant-abc",
"roleIds": [
"role-finance-manager",
"role-report-viewer"
]
}
// Response
{
"groupId": "group-guid",
"groupName": "finance-team",
"memberCount": 0,
"createdAt": "2026-05-25T10:00:00Z"
}
Group Membership Management
// Add users to a group
POST /passport/admin/groups/{groupId}/members
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"userIds": ["user-guid-1", "user-guid-2", "user-guid-3"],
"tenantId": "tenant-abc"
}
// Remove a user from a group
DELETE /passport/admin/groups/{groupId}/members/{userId}
Authorization: Bearer {admin-token}
// List group members
GET /passport/admin/groups/{groupId}/members?page=1&pageSize=50
Authorization: Bearer {admin-token}
// List groups for a user
GET /passport/admin/users/{userId}/groups
Authorization: Bearer {admin-token}
Group-Based Resource Policies
Resource policies can target groups using the group: prefix in subjectIds. All current and future members of the group automatically inherit the policy:
{
"resourceType": "workflow",
"resourceId": "payroll-workflow-guid",
"effect": "Allow",
"permission": "workflow.initiate",
"subjectIds": ["group:group-guid-finance-team"],
"description": "All finance team members can initiate payroll"
}
IMembershipProvider and Groups
The IMembershipProvider returns both directly-assigned roles and group-derived roles in a single call. The policy engine does not distinguish the source — all resolved role IDs are evaluated together.
// For a user in group "finance-team" with direct role "viewer":
var groups = await membership.GetUserGroupsAsync("user-guid", "tenant-abc", ct);
// Returns: ["viewer", "finance-manager", "report-viewer"]
// viewer = direct assignment
// finance-manager, report-viewer = from finance-team group
Bulk Import from External Directory
// Sync groups from Azure AD or Okta at tenant onboarding
POST /passport/admin/groups/sync-from-provider
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"provider": "AzureAD",
"tenantId": "tenant-abc",
"groupFilters": ["Finance*", "IT-*", "HR-Managers"],
"defaultRoleMapping": {
"Finance*": ["finance-manager"],
"IT-*": ["admin"],
"HR-Managers": ["manager"]
},
"syncMembership": true
}
// Sync runs asynchronously — returns a job ID
{
"syncJobId": "sync-job-guid",
"status": "queued",
"estimatedMinutes": 2
}
When a user leaves the organization, removing them from all groups (or disabling their account) immediately revokes all group-derived permissions. No need to audit individual role assignments. For organizations with hundreds of users, group-based access management dramatically reduces administrative overhead.