The key is the principal: stolen Okta service-app credentials, headless admin
An Okta service app signs in with a private key and no user, so MFA and password resets are irrelevant. Steal the key and you drive the admin API headlessly.
An Okta OAuth service app authenticates with the client-credentials grant using a private key. There is no user, no interactive sign-in, and no MFA. The principal is the key.
How the attack works
An attacker steals that private key from a CI pipeline or config store and mints admin-scoped access tokens off the app’s normal source and schedule. With those tokens they drive the Okta management API headlessly, enumerating users and reading admin data with no user session in the path. They then grant the app additional admin scopes to widen its reach and create a standing API token so access survives even if the original key is later rotated. This maps to T1552, Unsecured Credentials, and T1528, Steal Application Access Token.
Why it works
Because there is no human behind client-credentials access, every user-centric control is bypassed. Resetting passwords and forcing MFA re-enrollment chase users who are not the principal, while the key keeps minting admin tokens.
How to fix it
Kill the key. Rotate or revoke the service app’s private key and revoke its granted scopes and admin role so it can no longer mint or use tokens, then audit what it touched, including any standing tokens it created. An address block is evadable and ignores the key. For the class, inventory all service apps and their scopes, store keys in a secrets manager with rotation, scope each app to least privilege, and alert on off-pattern client-credentials grants and scope changes. Treat a service-app key as a non-human Tier-0 credential.
Practice it
We built this as a GraphLattice Range scenario so security teams learn to contain a headless principal whose identity is a key, not a person.