Role Mappings
Role Mappings
Section titled “Role Mappings”Configure automatic role assignment based on identity provider groups.
Overview
Section titled “Overview”Role mappings automatically assign Mantis roles to users based on their IdP group membership, enabling centralized access control management.
How It Works
Section titled “How It Works”Login Flow with Role Sync
Section titled “Login Flow with Role Sync”Role Sync Modes
Section titled “Role Sync Modes”| Mode | Description | Use Case |
|---|---|---|
additive | Only add roles, never remove | Default, safe for mixed environments |
full | Sync exactly to IdP groups | Full IdP control of roles |
none | Don’t sync roles at all | Manual role management only |
Creating Role Mappings
Section titled “Creating Role Mappings”Database Schema
Section titled “Database Schema”CREATE TABLE identity_provider_role_mappings ( id UUID PRIMARY KEY, provider_id UUID NOT NULL REFERENCES identity_providers(id) ON DELETE CASCADE, external_group TEXT NOT NULL, role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE, priority INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMP NOT NULL DEFAULT NOW(), UNIQUE (provider_id, external_group, role_id));Via Lens UI
Section titled “Via Lens UI”- Navigate to Admin → Identity Providers
- Select the provider
- Click Role Mappings tab
- Click Add Mapping
- Enter:
- External Group: Group name from IdP (exact match)
- Role: Mantis role to assign
- Priority: Higher priority mappings processed first
Via SQL (Direct)
Section titled “Via SQL (Direct)”-- Map IdP group "Mantis-Admins" to admin roleINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id, priority)SELECT (SELECT id FROM identity_providers WHERE name = 'Okta'), 'Mantis-Admins', (SELECT id FROM roles WHERE name = 'admin'), 100;
-- Map IdP group "Mantis-Operators" to operator roleINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id, priority)SELECT (SELECT id FROM identity_providers WHERE name = 'Okta'), 'Mantis-Operators', (SELECT id FROM roles WHERE name = 'operator'), 50;
-- Map IdP group "Everyone" to viewer roleINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id, priority)SELECT (SELECT id FROM identity_providers WHERE name = 'Okta'), 'Everyone', (SELECT id FROM roles WHERE name = 'viewer'), 10;Sync Mode Configuration
Section titled “Sync Mode Configuration”Configure Sync Mode
Section titled “Configure Sync Mode”role_sync_mode is not yet exposed through the REST API. Set it directly in the database:
UPDATE identity_providers SET role_sync_mode = 'full' WHERE id = '$IDP_ID';Valid values are additive (default), full, and none.
Additive Mode (Default)
Section titled “Additive Mode (Default)”- Roles from IdP groups are added
- Existing roles are preserved
- Roles are never removed
Full Sync Mode
Section titled “Full Sync Mode”- Roles controlled by this provider’s mappings are synced to current IdP group membership
- Roles whose corresponding IdP group the user no longer belongs to are removed
- Roles not managed by any mapping for this provider are preserved
- System roles (is_system=true) are never removed
None Mode
Section titled “None Mode”- Role mappings are ignored
- Roles must be assigned manually
- Default role (if configured) is still assigned to new users
Priority System
Section titled “Priority System”How Priority Works
Section titled “How Priority Works”Higher priority mappings are processed first:
SELECT external_group, role_idFROM identity_provider_role_mappingsWHERE provider_id = $provider_idORDER BY priority DESC;Example Configuration
Section titled “Example Configuration”| External Group | Role | Priority |
|---|---|---|
| Mantis-SuperAdmins | admin | 100 |
| Mantis-Admins | admin | 90 |
| Mantis-Operators | operator | 50 |
| Mantis-Viewers | viewer | 30 |
| Everyone | viewer | 10 |
With this configuration:
- Users in
Mantis-SuperAdminsgetadminrole - Users in
Mantis-Operatorsgetoperatorrole - Users in only
Everyonegetviewerrole
Priority Best Practices
Section titled “Priority Best Practices”100+ : Critical/emergency access90 : Full admin access50 : Standard operational roles30 : Limited access roles10 : Default/catch-all rolesGroup Name Matching
Section titled “Group Name Matching”Exact Match
Section titled “Exact Match”Group names must match exactly (case-sensitive):
IdP Group: "Mantis-Admins" ✓ Matches "Mantis-Admins"IdP Group: "Mantis-Admins" ✗ Does not match "mantis-admins"IdP Group: "Mantis-Admins" ✗ Does not match "Mantis Admins"Provider-Specific Group Names
Section titled “Provider-Specific Group Names”| Provider | Group Format | Example |
|---|---|---|
| Okta | Group name | Mantis-Admins |
| Azure AD | Object ID or name | 12345678-... or Mantis-Admins |
| Keycloak | Group path | /organization/team/admins |
| Auth0 | Role/group name | Mantis:admin |
Azure AD Group IDs
Section titled “Azure AD Group IDs”Azure AD may send group Object IDs instead of names:
{ "groups": [ "12345678-abcd-1234-abcd-123456789012", "87654321-dcba-4321-dcba-987654321098" ]}Create mappings using Object IDs:
INSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id)VALUES ('$provider_id_uuid', '12345678-abcd-1234-abcd-123456789012', '$role_id_uuid');Multiple Roles
Section titled “Multiple Roles”One Group → Multiple Roles
Section titled “One Group → Multiple Roles”A single IdP group can map to multiple Mantis roles:
-- DevOps group gets both operator and target-manager rolesINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id)SELECT (SELECT id FROM identity_providers WHERE name = 'Okta'), 'DevOps', idFROM roles WHERE name IN ('operator', 'target-manager');User in Multiple Groups
Section titled “User in Multiple Groups”Users in multiple groups receive all mapped roles (additive):
IdP Groups: [Mantis-Operators, Mantis-Deployers]Mappings: - Mantis-Operators → operator - Mantis-Deployers → deployerResult: User gets [operator, deployer]Role Sync Algorithm
Section titled “Role Sync Algorithm”Additive Mode
Section titled “Additive Mode”# Pseudocodedef sync_additive(user, idp_groups, mappings): for group in idp_groups: if group in mappings: for role in mappings[group]: if role not in user.roles: user.roles.append(role)Full Sync Mode
Section titled “Full Sync Mode”# Pseudocodedef sync_full(user, idp_groups, mappings): mapped_roles = set() for group in idp_groups: if group in mappings: mapped_roles.update(mappings[group])
# Add new roles for role in mapped_roles: if role not in user.roles: user.roles.append(role)
# Remove unmapped roles (except system roles) for role in user.roles: if role in all_mapped_roles and role not in mapped_roles: if not role.is_system: user.roles.remove(role)Common Patterns
Section titled “Common Patterns”Basic Tier Pattern
Section titled “Basic Tier Pattern”-- Admin tierINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id, priority)VALUES ($provider, 'Mantis-Admins', $admin_role, 100);
-- Operator tierINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id, priority)VALUES ($provider, 'Mantis-Operators', $operator_role, 50);
-- Viewer tier (default)INSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id, priority)VALUES ($provider, 'Everyone', $viewer_role, 10);Environment-Based Pattern
Section titled “Environment-Based Pattern”-- Production adminsINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id)VALUES ($provider, 'Prod-Admins', $prod_admin_role);
-- Staging adminsINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id)VALUES ($provider, 'Staging-Admins', $staging_admin_role);
-- Development accessINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id)VALUES ($provider, 'Developers', $dev_role);Tenant-Based Pattern
Section titled “Tenant-Based Pattern”-- Tenant A operatorsINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id)VALUES ($provider_tenant_a, 'TenantA-Operators', $operator_role);
-- Tenant B operatorsINSERT INTO identity_provider_role_mappings (provider_id, external_group, role_id)VALUES ($provider_tenant_b, 'TenantB-Operators', $operator_role);Troubleshooting
Section titled “Troubleshooting”Roles Not Syncing
Section titled “Roles Not Syncing”-
Verify groups claim:
Terminal window # Check if groups are in ID tokencurl -s "https://api.mantis.local/api/v1/auth/oidc/providers" -
Check claim configuration:
SELECT groups_claim FROM identity_providers WHERE id = $provider_id; -
Verify mapping exists:
SELECT * FROM identity_provider_role_mappingsWHERE provider_id = $provider_id;
Wrong Roles Assigned
Section titled “Wrong Roles Assigned”-
Check sync mode:
SELECT role_sync_mode FROM identity_providers WHERE id = $provider_id; -
Verify group names match exactly
-
Check priority order of mappings
Roles Disappearing (Full Sync)
Section titled “Roles Disappearing (Full Sync)”- Verify group membership in IdP
- Check if role is system role (won’t be removed)
- Consider switching to additive mode
Groups Not in Token
Section titled “Groups Not in Token”- Configure groups scope in IdP
- Add groups claim to ID token configuration
- Check group limit (some IdPs limit groups returned)
Best Practices
Section titled “Best Practices”Naming Conventions
Section titled “Naming Conventions”| Approach | Example |
|---|---|
| Application prefix | Mantis-Admins, Mantis-Operators |
| Role suffix | Platform-Admin, Platform-Viewer |
| Clear hierarchy | Org/Team/Role |
Security Recommendations
Section titled “Security Recommendations”- Use additive mode unless full control needed
- Audit mappings regularly
- Test changes in staging first
- Document mappings for operations team
- Review role assignments periodically in the Mantis UI
Change Management
Section titled “Change Management”- Review before production deployment
- Notify affected users of changes
- Have rollback plan ready
- Test with representative users
Next Steps
Section titled “Next Steps”- External Identities - Manage user links
- OIDC Configuration - Provider setup
- Roles - Role configuration
