Discovering Unexpected Okta Attack Paths with BloodHound

Read Time

15 mins

Published

Mar 23, 2026

Share

TL;DR: OktaHound is a new data collector for the Okta Platform that ingests information about entities and their relationships within an Okta organization and represents them as nodes and edges in BloodHound’s graph database. Security professionals can then visualize their Okta environments, discover policy violations in their security model, and search for possible attack paths and privilege escalations. After unleashing the full power of BloodHound’s OpenGraph by ingesting data from multiple sources, hybrid paths and unexpected security dependencies between Okta and connected resource or identity providers will start lighting up.

Why Okta?

Okta Platform (A.K.A. Okta Workforce Identity Cloud) is a popular cloud-based enterprise identity and access management (IAM) solution.

Figure 1. Okta Workforce Identity Cloud overview.

Okta is an interesting target for attackers, as organizations widely use it to manage access to their cloud and on-premises applications. When connected to a third-party mobile device management (MDM) solution like Jamf or Intune, Okta could indirectly be misused for endpoint takeover. Compromising an Okta organization (i.e., tenant) could thus provide attackers with access to a wide range of resources and data.

Figure 2. Example of an Okta tenant connected to third-party systems.

Having said that, Okta organizations seem to be secure by default. Multi-factor authentication (MFA) is enforced for all users and re-authentication is required for sensitive administrative tasks.

Figure 3. Okta admin flow requiring re-authentication for sensitive actions.

Moreover, Okta has taken steps to mitigate privilege elevation paths through role-based access control (RBAC). For example, only Super Administrators can manage groups with administrative roles. Most attack paths thus arise from misconfigurations, such as excessive role assignments, weak authentication policies, insecure application integrations, and sensitive credential exposure.

It is also important to note that a non-privileged Okta user might have administrative access in connected applications, such as GitHub Enterprise Cloud or Amazon Web Services (AWS). Hybrid attack paths between (insecure) on-premises Active Directory environments and Okta are also possible.

đź’ˇ

The other main product in Okta’s portfolio is Auth0, previously known as Customer Identity Cloud. For the time being, Auth0 is outside of the scope of our research.

Prior Work

The following blog posts provide great insights into Okta attack vectors and techniques:

Here are some interesting GitHub repositories related to Okta security research:

Introducing OktaHound

Today, we are publicly releasing OktaHound Beta: our data collector for BloodHound. This command-line interface (CLI) application for Windows, Linux, and macOS connects to the Okta Management API, fetches data about users, groups, devices, applications, roles, policies, identity providers, directory integrations, and other entities within an Okta organization, and exports the information to the OpenGraph JSON format. The graph data can then be uploaded to BloodHound for visualization and attack path analysis.

Figure 4. OktaHound CLI collection and export to OpenGraph JSON.
Figure 5. BloodHound visualization of OktaHound role assignments.

Required Permissions

OktaHound primarily targets the blue teamers and must be registered as an API Services application in an Okta organization.

Figure 6. Okta Admin Console: registering OktaHound as an API Services app.

In accordance to the principle of least privilege, the application then needs to be granted the following OAuth 2.0 scopes:

  • okta.orgs.read
  • okta.users.read
  • okta.groups.read
  • okta.apps.read
  • okta.appGrants.read
  • okta.devices.read
  • okta.roles.read
  • okta.apiTokens.read
  • okta.agentPools.read
  • okta.idps.read
  • okta.authorizationServers.read
  • okta.oauthIntegrations.read
  • okta.policies.read
  • okta.features.read
  • okta.realms.read
  • okta.realmAssignments.read
  • okta.logs.read
Figure 7. Okta Admin Console: granting OAuth scopes to the API Services app.

The application also needs to be assigned the Super Administrators role, permissions of which are filtered by the scopes listed above. OktaHound thus cannot perform any modifications in Okta.

As an alternative to registering OktaHound as an application in Okta, the collector can use (stolen) API tokens of Super Admins as well. Red teamers could use this approach to map outbound hybrid attack paths targeting external systems. Blue teamers should avoid using Okta API tokens to authenticate OktaHound, as they do not provide granular access control.

OktaHound Extension Schema

OktaHound extends the BloodHound schema with the following node kinds:

Icon Node Kind
Okta_AgentOkta_Agent
Okta_AgentPoolOkta_AgentPool
Okta_ApiServiceIntegrationOkta_ApiServiceIntegration
Okta_ApiTokenOkta_ApiToken
Okta_ApplicationOkta_Application
Okta_AuthorizationServerOkta_AuthorizationServer
Okta_ClientSecretOkta_ClientSecret
Okta_CustomRoleOkta_CustomRole
Okta_DeviceOkta_Device
Okta_GroupOkta_Group
Okta_IdentityProviderOkta_IdentityProvider
Okta_JWKOkta_JWK
Okta_OrganizationOkta_Organization
Okta_PolicyOkta_Policy
Okta_RealmOkta_Realm
Okta_ResourceSetOkta_ResourceSet
Okta_RoleOkta_Role
Okta_RoleAssignmentOkta_RoleAssignment
Okta_UserOkta_User

OktaHound creates the following edge kinds:

Edge NameDescriptionTraversable
Okta_AddMemberAbility to add or remove members in scoped Okta groupsâś…
Okta_AgentMemberOfMembership of an Okta agent in an agent poolâś…
Okta_AgentPoolForRelationship between an AD agent pool and its backing AD applicationâś…
Okta_ApiTokenForUser ownership of an Okta API tokenâś…
Okta_AppAdminApplication administrator role assignmentâś…
Okta_AppAssignmentAssignment of users or groups to an Okta application❌
Okta_ContainsContains relationship between the Okta organization and its objectsâś…
Okta_CreatorOfCreator relationship for API service integrations❌
Okta_DeviceOfOwnership relationship between a device and its assigned user❌
Okta_GroupAdminGroup administrator role assignmentâś…
Okta_GroupMembershipAdminGroup membership administrator role assignmentâś…
Okta_GroupPullImport of group memberships from an external applicationâś…
Okta_GroupPushProvisioning of group memberships to an external application❌
Okta_HasRoleAssignment of a built-in or custom role to a principal❌
Okta_HasRoleAssignmentRelationship between a principal and a role assignment❌
Okta_HelpDeskAdminHelp desk administrator role assignmentâś…
Okta_HostsAgentRelationship between an AD server and the Okta agent running on that hostâś…
Okta_IdentityProviderForTrust relationship between an identity provider and Okta usersâś…
Okta_IdpGroupAssignmentIdentity provider group assignment to an Okta group❌
Okta_InboundOrgSSOSingle sign-on (SSO) from an external organization into Oktaâś…
Okta_InboundSSOSSSO from an external identity provider into Oktaâś…
Okta_KerberosSSOAgentless desktop SSO relationship from on-premises AD user account to Okta AD applicationâś…
Okta_KeyOfJSON Web Key (JWK) associated with an Okta applicationâś…
Okta_ManageAppAbility to manage scoped Okta applicationsâś…
Okta_ManagerOfManager relationship between Okta users❌
Okta_MemberOfMembership of a user in an Okta groupâś…
Okta_MembershipSyncBidirectional synchronization between Okta groups and external groupsâś…
Okta_MobileAdminMobile administrator role assignmentâś…
Okta_OrgAdminOrganization administrator role assignmentâś…
Okta_OrgSWASecure Web Authentication from an Okta application to an external organization❌
Okta_OutboundOrgSSOSSO from an Okta application to an external organizationâś…
Okta_OutboundSSOSSO from Okta to an external identity providerâś…
Okta_PasswordSyncPassword synchronization between user accounts via AD integration, Org2Org, or SCIMâś…
Okta_PolicyMappingAssociation of a policy with an Okta application❌
Okta_ReadClientSecretAbility to read client secrets for scoped Okta applicationsâś…
Okta_ReadPasswordUpdatesApplication can read password updates over the SCIM protocolâś…
Okta_RealmContainsContains relationship between an Okta realm and its usersâś…
Okta_ResetFactorsAbility to reset MFA factors for scoped Okta usersâś…
Okta_ResetPasswordAbility to reset passwords or temporary credentials for scoped Okta usersâś…
Okta_ResourceSetContainsMembership of objects within an Okta resource setâś…
Okta_ScopedToScope relationship between a role assignment and its target❌
Okta_SecretOfClient secret associated with an application or service integrationâś…
Okta_SuperAdminSuper Administrator role assignmentâś…
Okta_SWASecure Web Authentication from Okta to an external application❌
Okta_UserPullImport of users from an external application❌
Okta_UserPushProvisioning of users to an external application❌
Okta_UserSyncBidirectional synchronization between Okta users and external identities❌

Built-In Roles

Each built-in Okta role assignment is modeled using a role-specific direct traversable edge, such as Okta_SuperAdmin or Okta_GroupAdmin, and indirect non-traversable Okta_HasRoleAssignment, Okta_ScopedTo, and Okta_HasRole edges.

Figure 8. Built-in role modeling example: role-specific direct traversable edge (Okta_SuperAdmin) based on the supporting non-traversable edges.
Figure 9. Built-in role modeling example: role assignment scoped to a group, with a traversable Okta_HelpDeskAdmin edge to the group’s members.

Custom Roles

Custom roles are modeled similarly to the built-in roles, but with these key differences:

  • They are always scoped to resource sets
  • Traversable edges are modeled using individual permissions
OAuth Permission(s)Edge
okta.users.manage
okta.users.credentials.manage

okta.users.credentials.manageTemporaryAccessCode
okta.users.credentials.resetPassword okta.users.credentials.expirePassword
Okta_ResetPassword
okta.users.manage
okta.users.credentials.manage
okta.users.credentials.resetFactors
Okta_ResetFactors
okta.groups.manage
okta.groups.members.manage
Okta_AddMember
okta.apps.manageOkta_ManageApp
okta.apps.clientCredentials.readOkta_ReadClientSecret
Figure 10. Modelling example of an Okta_ResourceSet and its Okta_ResourceSetContains edges.
Figure 11. Modelling example of a custom role (”Authentication Admins”) and the resulting traversable edges (Okta_ResetPassword and Okta_ResetFactors).

Okta Attack Paths

Short Native Attack Paths

One thing that comes as a surprise is that native Okta attack paths are relatively short when compared to our security models of Active Directory (AD) and Microsoft Entra ID. There are multiple reasons for this:

  • Okta does not support group nesting and only users can be members of groups
  • Many theoretical privilege elevation paths are intentionally mitigated by only allowing Super Administrators (the most privileged role in Okta) to modify users, groups, and applications that have role assignments, built-in or custom
  • Lateral movement between connected computers is extremely limited by the absence of built-in device management capabilities, such as Group Policy. Moreover, Okta authentication is not integrated with popular remote computer management protocols like RDP, SSH, SMB, WMI, or WinRM

On the other hand, real-world Okta deployments are seldom isolated and often contain inbound and outbound trust relationship in the form of SAML/OIDC SSO, password replication, or group membership synchronization. These hybrid or cross-technology relationships are part of OktaHound’s data model.

Overprivileged Auditors

While trying to come up with the least-privilege set of permissions required to run OktaHound, we stumbled upon these practical problems:

  • Users assigned the Read-Only Administrators built-in role cannot read role assignments within Okta environments. A custom role with this permission (IAM) can be created, though
  • We were unable to figure out a way of delegating the permission to read OAuth 2.0 scopes granted to Okta Applications. Only the Super Administrators role seems to be able to read application permissions

As a consequence, security auditors cannot use the Read-Only Administrators role. It is therefore safe to assume that many external security auditors are assigned the Super Administrators role.

Reading Application Secrets

As soon as an Okta-integrated service application is assigned an administrative role in Okta, users assigned the Application Administrators role scoped to this service application are no longer able to modify any of its properties. However, we identified these built-in roles to be able to read pre-existing client secrets of privileged service applications:

  • Application Administrators
  • Read-Only Administrators
  • API Access Management Administrators
Figure 12. A user with Application Administrators role assignment can compromise Super Admin applications by reading their client secrets.

Malicious actors could easily abuse this behavior to first read the client secret of a highly-privileged application and then authenticate with it against Okta, impersonating the application identity. This could lead to unexpected privilege elevation, which we model using the Okta_ReadClientSecret edge.

đź’ˇ

Before publishing this article, we contacted Okta in this matter through their official bug bounty program. We were told that this behavior was intentional and Okta did not consider it a security issue. Interestingly, our colleague Andy Robbins has discovered that Ping One, a competing IAM product, had the same behavior. On the other hand, Microsoft’s Entra ID never reveals existing client secrets, not even to Global Administrators.

SCIM Password Synchronization

The SCIM protocol has become a de-facto standard for identity synchronization, so Okta naturally supports SCIM for user provisioning to/from external systems, including password change notifications.

A well-known attack path exists where Application Administrators can modify the endpoint to which Okta sends password updates for assigned users. Malicious actors could thus redirect the password updates to a URL under their control and potentially read the fresh cleartext password of a highly privileged Okta user. Another variant of this attack would be registering a new SCIM application object and assigning the Everyone group to it.

In OktaHound we model this permission using the Okta_ReadPasswordUpdates and Okta_PasswordSync edges.

Figure 13. Privilege escalation example from Application Admin to Super Admin through Okta_ReadPasswordUpdates.
Figure 14. Example of Okta_PasswordSync and the related edges in the OktaHound model.

Secure Web Authentication (SWA)

As an alternative to the recommended OIDC and SAML single sign-on protocols, Okta provides a feature called Secure Web Authentication (SWA). It is basically an enterprise password manager, which allows users to save web application passwords into Okta and then use the autofill capability of the Okta Browser Plugin. Administrators can also define common passwords all users share.

Although these saved passwords are never directly exposed to the end-user, the F12 developer tools in most desktop browsers and an undocumented Okta API endpoint can be misused to read the cleartext passwords of the currently logged-in user, as detailed in Luke Jennings (PushSecurity): Abusing Okta’s SWA authentication blog post.

We model this security risk of cleartext password exposure using two edges: Okta_OrgSWA and Okta_SWA.

Figure 15. Modelling example of Okta SWA app setup and shared credentials concept.
Figure 16. Modelling example of Okta SWA app setup and shared credentials concept.

The management plane for the SWA feature is very limited and we were unable to fetch the inventory of saved passwords for all users through the Okta Management API. Our security model of the SWA feature is thus incomplete.

Okta Workflows

Workflows in Okta provide a robust way to automate tasks related to user provisioning and deprovisioning. To achieve this, Okta must be granted non-trivial permissions in connected systems. Here is an example of permissions needed by the Microsoft Office 365 connector:

Figure 17. Example Okta Workflows connector permissions.

Anyone in control of the workflow could perform administrative actions in Microsoft Entra.

As there is no documented API for reading the information about existing workflows and their configuration, workflows are currently absent in our security model. BloodHound can only be used to analyze the Workflow Administrators role assignment:

Figure 18. BloodHound view for Okta Workflow Administrators role assignment.

Using Users With API Tokens Instead of Service Apps

While performing Okta security assessments, we have seen many applications use regular user accounts with API token authentication, which are basically passwords that bypass MFA requirements, instead of using dedicated API Services registrations with JWKs and fine-grained permissions. This goes against the principle of least-privilege and may lead to unintended credential disclosure.

The traversable Okta_ApiTokenFor edges represent the API token assignments for users in Okta.

Figure 19. Okta API token graph modeling: Okta_ApiTokenFor edges representing token ownership for user principals.

Agentless Desktop Single Sign-on

With agentless Desktop SSO (DSSO), you don’t need to deploy IWA agents in your Active Directory domains to implement DSSO functionality. This reduces or eliminates the maintenance overhead and provides high availability as Okta assumes responsibility for Kerberos validation.

Figure 20. Okta Agentless Desktop SSO (DSSO) authentication overview.

Whoever has control over the Kerberos SSO account in Active Directory can impersonate all users, except secondary authentication factors. For a red team-oriented perspective on how Okta’s Kerberos SSO / DSSO works (and how it can be abused in practice), see Adam Chester’s Okta for Red Teamers write-up.

Figure 21. Modelling example of Kerberos SSO account in AD.

Active Directory Agents

Okta’s Active Directory agents can be installed on member servers to provide synchronization of AD users and groups to/from Okta. This capability is thus similar to Microsoft’s Entra Connect. Unlike Microsoft, Okta recommends for the synchronization service accounts to be added to the Domain Admins group in AD, granting Okta administrators unlimited control over Active Directory. As managed service accounts are not supported by Okta, a human must set and manually rotate service account passwords.

Figure 22. Okta AD agent Management Utility verifying the service account’s membership of Domain Admins.

The relationships between servers and agents they are hosting are represented using the Okta_HostsAgent, Okta_AgentMemberOf, and Okta_AgentPoolFor edges.

Figure 23. OktaHound AD agent relationships in the graph (Okta_HostsAgent, Okta_AgentMemberOf, Okta_AgentPoolFor).

The potential for privilege elevation exists in both directions: By taking over an AD user account synchronized onto a privileged account in Okta, an attacker could move from on-premises to the cloud. Alternatively, if an Okta group is pushed into Active Directory and assigned some permissions there, an Okta user in control over the group membership could add themselves to said group and perform privilege elevation from Okta to Active Directory. OktaHound uses the following edges to represent these relationships:

  • Okta_UserSync
  • Okta_MembershipSync
  • Okta_PasswordSync
  • Okta_UserPull
  • Okta_UserPush
  • Okta_GroupPull
  • Okta_GroupPush
Figure 24. Modelling example of the Okta_UserSync edge.
Figure 25. Modelling example of the Okta_MembershipSync edge.

As previously mentioned, well-designed Okta authentication policies can render user impersonation less feasible. Luckily for attackers, many users are susceptible to MFA fatigue.

Credential Hygiene

Although this is not BloodHound’s primary use case, data collected by OktaHound also provides insight into an organization’s credential hygiene. Security auditors can generate simple reports containing stale privileged users or identify applications with “eternal” client secrets. The data can even be exported from BloodHound into Excel.

Figure 26. Non-active privileged Okta users identified using Cypher in BloodHound.

Join Us and Stay Tuned

Please join us in the #okta channel of the BloodHound Community Slack workspace if you want to chat about attack paths in Okta or the usage of OktaHound. You are also welcome to open an issue or pull request on GitHub.

Our security research on Okta attack paths is still ongoing. We will announce additional product capabilities at SO-CON.

Michael Grafnetter

Principal Security Researcher

Michael Grafnetter is a Principal Security Researcher at SpecterOps specializing in identity security. He is the author of the DSInternals PowerShell module and creator of the Shadow Credentials attack.

Ready to get started?

Book a Demo