Most Okta orgs delegate administration with a handful of broad standard roles, so a help desk analyst or app owner ends up holding far more power over users, groups and applications than the job needs. Okta custom admin roles fix this by pairing a hand-picked set of permissions with a resource set that limits where those permissions apply. This guide is a design manual for that model: how assignments are evaluated, how to build resource sets that exclude administrators, which permissions carry hidden dependencies or quietly expose secrets, how to test and roll out, and which System Log events to watch. It is for Okta administrators and identity architects who already protect Super Admin and the Admin Console; those controls are covered in the Okta Security Hardening Guide and are not repeated here.
This is an independent guide from NHI Mgmt Group, based on Okta's public documentation as of November 2026. It is not sponsored or reviewed by Okta. Product features change, so confirm settings against Okta's current documentation.
Key takeaways
- An assignment is three things, not one. Okta evaluates an admin (user, group or app), a role (standard or custom) and a resource set together, so a well-designed role on an over-broad resource set is still over-privileged.
- Design resource first. Okta's own best practice is to decide which users, groups and apps an admin should touch before choosing permissions, then split view and edit into separate assignments.
- Keep administrators out of every delegated resource set. Build a non-admin user group with a group rule and scope help desk roles to it; Okta notes that adding any standard role to the same admin removes the protection custom roles give Super Administrator users.
- Privileges add up. Effective rights are the union of every direct and group-inherited standard and custom role, so a narrowly scoped standard role plus a custom role on all groups means all groups.
- Some permissions are secrets in disguise. View client credentials exposes OAuth client secrets, Manage applications also grants Manage directories and Run imports can create users; treat these as privileged and log every change to roles, resource sets and bindings.
How Okta evaluates an admin assignment
Okta describes a custom admin role assignment as three components. The admin is a user, a group or an app that receives the permissions. The role is a set of permissions, either one of Okta's standard roles or a custom role you define. The resource set is a collection of resources (users, groups, apps and other objects) that the role is constrained to. Resource sets apply only to custom roles; standard roles start org-wide and can only be narrowed through target operations on users, groups or clients where the role supports targets.
In the Management API, the combination is called a binding: a unique pairing of principal, resource set and custom role with its own ID. One resource set can carry many bindings, which is how one "EMEA employees" set can serve both a viewer role and an editor role. Resources inside a set are identified by an Okta Resource Name (ORN) in the form orn:{partition}:{service}:{tenantId}:{objectType}:{objectId}, or by REST URL where an Okta API exists. The optional contained_resources suffix targets the contents of a container rather than the container: orn:{partition}:directory:{orgId}:groups:{groupId}:contained_resources means the users in a group, not the group object.
| Aspect | Standard roles | Custom roles |
|---|---|---|
| Permissions | Fixed by Okta (13 standard roles, from Super Admin to AI Agent Admin) | Chosen individually from the permission catalogue |
| Default reach | Org-wide until targets are added | Only the resources in the bound resource set |
| Scoping mechanism | Targets (specific groups or apps) where supported | Resource set, plus resource set conditions and permission conditions |
| Who can assign | Super Admin | Super Admin (only Super Admin can add or remove administrators) |
| Effect on Super Administrator users | Some roles can act on super admins in managed groups (for example clearing sessions) | Cannot act on Super Administrator users while the admin holds no standard role |
| Limits | Not applicable | 100 roles per org, 10,000 resource sets, 1,000 resources per set, 1,000 admins per role and resource set combination |
The rule that matters most for design is additive evaluation. Okta's developer documentation states that an admin's effective privileges combine direct and group-inherited standard roles with direct and group-inherited custom roles, and gives the example that a standard role limited to one group plus a custom role covering all groups results in management of all groups. A tidy custom role does nothing if the same person also inherits Org Admin from a forgotten group.
Designing resource sets
A resource set can hold users (selected through named groups or realms, or all users), groups, applications (specific instances, all apps of a type such as every Salesforce instance, or all apps), delegated Workflows flows, authorization servers, identity providers, customizations, devices, policies, service accounts, IAM resources and several newer types, some of which Okta marks as Early Access. Only super admins can create resource sets, under Security > Administrators > Resources.
Patterns that work
- Population sets: one set per population an admin team serves ("UK employees", "Contractors", "Retail store staff"), built from groups that are themselves populated by group rules from HR attributes, so membership follows the HR record rather than manual edits.
- Non-admin user set: a group rule that includes Everyone and excludes every group that holds an admin role, as Okta's support guidance shows with the
!(NOT) operator in Okta Expression Language. Assign admin roles only to groups, never to individuals, so the exclusion stays complete. - Application portfolio sets: one set per business application family or per app owner, using app instances or app types; Okta's example separates "All Onboarding Apps" from "Profile Source Apps" so only the second gets import rights.
- View-wide, edit-narrow: an all-inclusive set for read access and a narrower set for change access, bound to separate roles. Okta's example lets a Los Angeles help desk view all United States employees but edit profiles only for Los Angeles employees.
- Exclusions with conditions: resource set conditions exclude specific apps or groups from an otherwise broad set (supported for Apps and Groups). Use them to carve high-value apps, such as finance systems, out of an "all apps" scope.
Edge cases to plan for
- Directory-sourced groups: AD and LDAP sourced groups can be resources, but Create users, Manage users' authenticator operations, Edit users' profile attributes and Manage group membership do not apply to them. Okta also notes the UI cannot show group origin, so two groups with the same name are indistinguishable; give directory groups unique names before scoping.
- Admin-privileged groups: once a group is assigned an admin role, only Super Admin can manage it. A delegated admin who could edit a group yesterday will be refused today if someone made it an admin group, which is the intended protection.
- Creation rights need org-wide scope: Create groups works only if the assignment covers the whole org, and admins can create authorization servers only if their role is scoped to all authorization servers. Decide deliberately whether a team should create objects or only manage existing ones.
- Workflows: custom admin roles cannot administer Okta Workflows itself, and the Workflows RBAC resource set cannot be assigned to a custom role. Delegated flows (Run and View) are the supported route; see the Okta Workflows security guide.
Choosing permissions: dependencies and hidden power
Okta's permission catalogue is long and grows each release. Most permissions are self-explanatory; the ones below carry dependencies or side effects that change the real privilege of a role.
| Permission | What Okta documents | Design implication |
|---|---|---|
| Edit users' group membership | Also requires Manage group membership | Grant both only on a set that excludes admin groups; membership of an app-assigned group is access to that app |
| Edit users' application assignments | Also requires Edit application's user assignments | Pair with an app-scoped set, not all apps |
| Edit users' authenticator operations, Reset users' authenticators, Reset users' passwords | Cover password resets and MFA, including YubiKey enrolment | This is account takeover power; scope to non-admin populations and pair with caller verification |
| Clear users' sessions | Also clears OAuth tokens | Useful for responders; disruptive if misused on service users |
| Manage applications | Also grants Manage directories | Wider than its name; prefer narrower app permissions where they meet the need |
| View client credentials | Exposes OAuth client secrets | Treat as a secret-read permission; grant to very few, never in a general app viewer role |
| Run imports | Can create users through imports | A provisioning path; scope to profile source apps only |
| Manage identity providers | Controls inbound identity providers | Federation trust is sign-in as anyone matched; keep to a dedicated, reviewed role |
| Manage policies | Resource sets can target the app sign-on policy or the Okta sign-on policy | Policy edits can weaken MFA; separate from user administration |
| Manage API tokens | User permission for API tokens | Tokens act with their creator's privilege; see How to audit Okta API tokens and service apps |
| View roles, resources and admin assignments | Also requires View users and their details and View applications and their details | Good for auditors; Read-only Admin is the standard alternative |
Permission conditions narrow user permissions further. For View users and their details, Create users and Edit users' profile attributes you can include or exclude specific profile attributes. The base attributes (First name, Last name, Username, Primary email and Mobile phone) always remain visible. Two caveats matter for design: if one role includes an attribute and another excludes it, the admin gets access, and excluded attributes can still appear in SAML-based API responses. Use conditions to keep regional help desks away from sensitive HR attributes, not as a hard data boundary.
Several actions remain outside custom roles entirely. Only Super Admin can add, remove or view administrators, assign admin privileges to groups or add users to admin-privileged groups, and Okta's support article confirms a custom role cannot grant administrator privilege to another user or service account. Super Admin also keeps log streaming, sensitive attributes, hooks, service account creation and Okta Support access. That is the boundary between this guide and the Super Admin controls in the Okta Security Hardening Guide.
A reference role catalogue
A small, named catalogue is easier to review than dozens of one-off roles. The example below suits a mid-size workforce org; names follow Okta's advice to make permissions and resources clear at a glance and to record detail in the description.
| Custom role | Core permissions | Resource set | Replaces |
|---|---|---|---|
| Help Desk L1 (Custom) | View users and their details, Unlock users, Reset users' passwords, Clear users' sessions | Non-admin users, by region | Help Desk Admin |
| Help Desk L2 MFA (Custom) | L1 plus Reset users' authenticators, Run delegated flow for a verified reset flow | Non-admin users, by region | Help Desk Admin or Group Admin |
| Lifecycle Operator | Activate, Suspend, Unsuspend, Deactivate users; Edit users' profile attributes with conditions | Contractors and joiner groups | Group Admin |
| App Owner, Finance | View applications, Edit app's user assignments, Edit groups' application assignments | Finance app instances only | App Admin |
| Federation Engineer | Manage identity providers, View policies | Named identity providers | Org Admin |
| API Platform Owner | Manage authorization server | Named authorization servers | API Access Management Admin |
| Brand Manager | Manage customizations | Specific brands | Org Admin |
| Identity Auditor | View roles, resources and admin assignments, View users, View applications | All users, all apps, IAM resources | Read-only Admin for review tasks |
Keep role definitions generic and put the scope in the resource set. "Help Desk L1" bound once to "UK non-admin users" and once to "US non-admin users" is easier to review than two near-identical roles. If a design nears Okta's 100-role limit, roles are being used for scope.
Implementation: phased rollout
- Inventory current assignments. Export the Admin role assignments report (Okta states admin reports are retrieved only from this Admin Console page, not by API) and list every standard role, how it is assigned (user or group) and the targets. Flag every Org Admin, App Admin with all apps, and Help Desk or Group Admin without targets.
- Map tasks to resources. For each admin team, write down the populations and apps they serve and the tasks they actually perform, using System Log activity by that team for the last 90 days.
- Build groups and resource sets. Create the non-admin user group rule, population groups and app portfolio sets. Name each set for its contents and add a description with owner and purpose.
- Build roles and test in preview. Create the custom roles in an Okta preview org first (ORNs use the
oktapreviewpartition) and test each one with a test admin account: confirm allowed actions succeed, and that resetting a Super Administrator user, editing an admin group and viewing client credentials fail where intended. - Pilot with one team. Bind the custom role to the pilot team's group and resource set, then remove their standard role assignment. Removing the standard role is the step that makes the protection real, because a standard role on the same admin undoes the custom role's restriction on Super Administrator users.
- Roll out by team and monitor. Move remaining teams in waves, watching for support tickets that reveal a missing permission. Add the permission to the role, not a standard role to the person.
- Roll back cleanly. If a wave breaks operations, re-add the previous standard role assignment from your inventory (Super Admin action), record why, fix the custom role and retry. Keep the inventory export as the rollback record.
- Codify. Manage roles, resource sets and bindings as code through the Management API so changes are reviewed and drift is visible. See the Infrastructure as Code Security Guide.
Decision guidance
- Standard role with targets or custom role: a standard role with group targets is acceptable when its fixed permission set genuinely matches the task and the targets exclude admins. Choose a custom role when the standard role carries unused permissions or you need view-wide, edit-narrow scoping.
- Small orgs: with one or two IT staff, the main win is removing Org Admin from daily accounts and using a single custom "IT Operations" role on a non-admin set, with Super Admin kept on separate accounts.
- Outsourced service desk: give the provider a custom role in their staff's own named accounts, assigned through a provider group, scoped to non-admin users, with no authenticator reset unless a verified reset flow runs. See the Vishing and Help Desk Social Engineering Awareness Guide.
- Apps and service clients as admins: Okta allows an app to be the admin principal. Give integrations a custom role on a narrow resource set rather than a standard role, and review them with human admins. See the How to Run an Access Review for Service Accounts guide.
Detection and measurement
Every change to the delegation model is logged in the System Log. Stream these events to your SIEM and alert on any change made outside an approved change window.
| Event type | Meaning | Suggested response |
|---|---|---|
iam.role.create, iam.role.delete, iam.role.update | Custom role created, deleted, renamed or re-described | Match to a change ticket |
iam.role.permissions.add, iam.role.permissions.delete | Permissions changed on a custom role | High priority when the permission is in the sensitive list above |
iam.role.permission.conditions.add, iam.role.permission.conditions.delete | Permission condition added or removed | Removal widens attribute access; review |
iam.resourceset.create, iam.resourceset.resources.add, iam.resourceset.resources.update, iam.resourceset.resources.delete | Resource set created or its contents changed | Alert when an admin group or "all" scope is added |
iam.resourceset.bindings.add, iam.resourceset.bindings.delete | Admin role assignment created or removed on a resource set | Alert on any binding to an individual user rather than a group |
user.account.privilege.grant, user.account.privilege.revoke | A user's admin privileges changed, including group-based roles | Alert on any standard role granted to a holder of a custom role |
group.privilege.grant, group.privilege.revoke | Admin privileges granted to or revoked from a group | Confirm the group is in the non-admin exclusion rule |
app.oauth2.client.privilege.grant, app.oauth2.client.privilege.revoke | Admin privileges for an OAuth 2.0 client app changed | Treat as a non-human admin grant; require an owner |
Okta's support guidance shows the same idea built with Workflows: trigger on a privilege grant, inspect which role was granted and whether it was assigned to a group or an individual, and alert the SOC if the standard Help Desk role reappears. For query patterns, see the Okta System Log Detection Guide.
Metrics that show the model is working:
- Number of accounts holding Org Admin or unscoped standard roles, trending to zero outside break-glass.
- Percentage of admin assignments made to groups rather than individuals (target 100%).
- Percentage of delegated resource sets that exclude admin-privileged groups (target 100%).
- Admins holding both a standard role and a custom role (target zero for help desk teams).
- Role, resource set and binding changes without a matching change record per quarter.
Common failure patterns
- Custom role added, standard role left in place: because privileges are additive, the old Help Desk Admin or Group Admin assignment keeps every right the custom role was meant to remove.
- "All users" in a help desk set: the role is scoped, but the scope includes administrators. Use the non-admin group rule and assign admin roles only by group so it stays complete.
- Roles used as scope: one role per region or team produces near-duplicate roles that drift apart and push the org towards the 100-role limit; put scope in resource sets.
- Read roles that read secrets: a generic "App Viewer" role with View client credentials hands OAuth client secrets to everyone who needs to see app settings.
- Ambiguous directory groups: two AD groups with the same name in a resource set, one of them far broader than intended, because the UI does not show origin.
- No owner for resource sets: sets grow as people add groups for convenience and nobody reviews them; record an owner in the description and include sets in access reviews.
Framework mapping
| Framework | Reference | How custom roles and resource sets support it |
|---|---|---|
| NIST SP 800-53 Rev. 5 | AC-6 Least Privilege, AC-6(5) Privileged Accounts, AC-6(7) Review of User Privileges | Minimum permissions per task, restricted to defined populations, reviewed periodically |
| NIST SP 800-53 Rev. 5 | AC-5 Separation of Duties, AC-2 Account Management | Split view and edit, separate federation and policy roles from user administration |
| NIST CSF 2.0 | PR.AA-05 | Access permissions defined, managed and reviewed with least privilege and separation of duties |
| CIS Controls v8.1 | Safeguard 5.4, Safeguard 6.8 | Restrict administrator privileges to dedicated admin accounts; define and maintain role-based access control |
| ISO/IEC 27001:2022 Annex A | A.5.15 Access control, A.5.18 Access rights, A.8.2 Privileged access rights | Documented, scoped and reviewed privileged access |
For the wider principles, see the Least Privilege Techniques Guide and the Authorisation Models Guide.
Practitioner checklist
- Export the Admin role assignments report and record every standard role, how it is assigned and its targets.
- Create a non-admin user group with a group rule that excludes every admin-privileged group, and assign admin roles only to groups.
- Build resource sets by population and app portfolio, named for their contents, with owner and purpose in the description.
- Use resource set conditions to exclude sensitive apps and groups from broad sets.
- Build a small catalogue of generic custom roles and bind scope through resource sets, splitting view and edit.
- Restrict View client credentials, Manage identity providers, Manage policies, Manage applications and Run imports to dedicated, reviewed roles.
- Test each role in a preview org, including negative tests against Super Administrator users and admin groups.
- Remove the standard role from every admin who receives a custom role.
- Alert on
iam.role.*,iam.resourceset.*and privilege grant events, especially grants to individuals. - Review roles, resource set contents and bindings quarterly, alongside the admins themselves; see the Access Reviews Guide.
Standards and references
- Okta: Custom admin roles
- Okta: Best practices for creating a custom role assignment
- Okta: Role permissions
- Okta: Create a resource set
- Okta Developer: Role assignment
- Okta Developer: Event types
- Okta Support: Create custom admin roles that prevent help desk operations on privileged users
- Okta: Resource set conditions
Related NHI Mgmt Group resources: Okta Security Hardening Guide · Okta System Log Detection Guide · How to audit Okta API tokens and service apps · Least Privilege Techniques Guide · Access Reviews Guide