When an attacker gets into an Okta tenant they inherit every application behind it, and the Okta System Log is usually the only place the takeover is visible before it spreads. The log records sign-ins, factor changes, admin actions, policy edits, API token use and OAuth activity in one schema, but it keeps only 90 days, streams on a best-effort basis, and needs detection logic that understands Okta's own fields. This guide explains the LogEvent structure, how to collect the log without gaps, which event types matter, and how to build and test detections for help desk takeovers, session theft, rogue identity providers and abused API tokens. It is for detection engineers and identity security teams. Configuration hardening is covered in the Okta Security Hardening Guide; this page goes deeper on the log itself.
Key takeaways
- Collect continuously or lose it. The System Log API returns nothing older than 90 days, and log streams are at-least-once with no replay, so a SIEM copy with gap monitoring is mandatory.
- Use polling requests for ingestion. Polling (no
until, ascending order) follows persistence time and never skips late events; bounded queries can miss delayed records. - Build on fields, not display messages.
eventType,outcome.result,securityContext.isProxy,client.ipAddress,authenticationContext.externalSessionIdandtarget[].typecarry the detection logic. - Admin and factor changes are the high-value events. MFA resets, privilege grants, new identity providers and policy edits are rare, high-signal and were central to the 2023 Super Admin takeovers.
- Treat API tokens and OAuth service apps as identities.
system.api_token.createand token use outside allowed network zones are as important as human sign-ins.
The LogEvent schema in practice
Every System Log record is a LogEvent object. The fields below are the ones detection logic depends on; all come from Okta's management API specification.
| Field | What it holds | Detection use |
|---|---|---|
uuid | Unique event identifier | Deduplication across polling and streams |
published | Event timestamp | Ordering and correlation (not usable inside a filter expression) |
eventType | Dotted event type, for example user.session.start | Primary key for every rule |
actor | Who acted: user, API token, app, or system (id, type, alternateId) | Separate human, token and system actions |
client | IP address, user agent, device, geographical context, zone | New IP, new country, unexpected network zone |
outcome | result (SUCCESS, FAILURE, SKIPPED, ALLOW, DENY, CHALLENGE, UNKNOWN) and reason, for example INVALID_CREDENTIALS | Failures, denials, FastPass phishing declines |
target | Array of affected entities (User, AppInstance, Group, PolicyRule and more) | Who was changed; search by type, never by array position |
authenticationContext | Authentication provider, credential type, externalSessionId | Tie every action back to one Okta session |
securityContext | ASN, AS organisation, ISP, domain, isProxy, risk, user behaviours | Anonymising proxy and hosting-provider sign-ins |
debugContext.debugData | Event-specific detail, for example request URI, threat suspected, behaviours | New device, new geolocation, ThreatInsight verdicts |
transaction | Request or job identifier | Group events from one API call or job |
severity, displayMessage | Okta's labels | Context only; do not build rules on display text |
Okta publishes a catalogue of more than 1,200 event types, tagged where they are Identity Engine only, eligible for event hooks, or carry a changeDetails object showing before and after values. Event types that include changeDetails, such as policy.lifecycle.update, are the most useful for configuration drift detections because they show exactly what changed.
Collecting the log without gaps
| Method | How it works | Limits | Use for |
|---|---|---|---|
| System Log API, polling request | GET /api/v1/logs with since, no until, sortOrder=ASCENDING; follow the next link forever | Ordered by persistence time, so published may be out of order; rate limits apply; 90-day window | SIEM ingestion |
| System Log API, bounded request | since and until both set; finite pages | Ordered by published, but rare delayed events may be missing | Investigations of a known window |
| Log streaming | Okta pushes all events to Amazon EventBridge or Splunk Cloud | At least once, can be duplicated or out of order, no replay, stream deactivated after two failed retries | Low-latency delivery where the target is supported |
| Admin Console System Log | Interactive search with the same expression syntax | Manual; 90 days | Triage |
- Create a dedicated collector identity: prefer an OAuth 2.0 service app with only the
okta.logs.readscope and a private key credential over an SSWS API token, which inherits the full permissions of the admin who created it. See the SaaS API Token Security Guide. - Poll, do not page by time: Okta warns that manually stepping
sinceanduntilwindows can skip or duplicate events. Persist the lastnextlink and resume from it after restarts. - Deduplicate on
uuid(the stream's event ID) and order onpublished, because both streams and polling can deliver out of order. - Monitor the pipe: alert on
system.log_stream.lifecycle.deactivate, on collector HTTP 429 errors, and on any gap of more than 15 minutes in a normally busy tenant. - Run both where practical: a stream for latency and a polling collector as the system of record means a deactivated stream does not lose data, since the stream cannot replay.
- Keep at least a year in the SIEM: many identity investigations start months after initial access, long after Okta's 90 days.
Query syntax matters for both collection and hunting. The filter parameter takes SCIM-style expressions (for example eventType eq "user.mfa.factor.reset_all" or eventType sw "system.idp.lifecycle"), q takes up to 10 keywords of 40 characters each, limit runs from 0 to 1,000, and an individual query times out after 30 seconds. Okta hashes the clientSecret value in the log, so log content is not a secret store, but treat exported logs as sensitive personal data all the same.
Event types that matter
| Area | Event types | Why it matters |
|---|---|---|
| Sessions and sign-in | user.session.start, user.authentication.sso, user.session.access_admin_app, user.session.end, user.session.clear | Baseline of who signs in from where; admin console access |
| MFA | user.authentication.auth_via_mfa, user.mfa.okta_verify.deny_push, user.mfa.attempt_bypass, user.mfa.factor.activate, user.mfa.factor.deactivate, user.mfa.factor.reset_all | Push fatigue, factor swaps after help desk resets, AiTM declines |
| Accounts | user.account.lock, user.account.reset_password, user.account.update_password, user.lifecycle.create, user.account.report_suspicious_activity_by_enduser | Spraying, takeover and user reports |
| Privilege | user.account.privilege.grant, group.privilege.grant, app.oauth2.client.privilege.grant, group.user_membership.add | Admin role assignment to users, groups and OAuth clients |
| Policy and zones | policy.lifecycle.update, policy.lifecycle.deactivate, policy.rule.update, policy.rule.deactivate, zone.update, security.attack_protection.settings.update | MFA removed from rules, network zones widened |
| Federation | system.idp.lifecycle.create, system.idp.lifecycle.update, system.idp.lifecycle.activate, user.authentication.auth_via_IDP | Rogue inbound identity providers used for impersonation |
| Authenticators | security.authenticator.lifecycle.deactivate, system.mfa.factor.deactivate | Org-wide factor disabled |
| API tokens | system.api_token.create, system.api_token.update, system.api_token.revoke, system.api_token.request_outside_allowed_range | Persistence and NHI misuse |
| OAuth and apps | app.oauth2.as.token.grant, app.oauth2.as.consent.grant, application.lifecycle.update, application.user_membership.add | Token issuance and app reconfiguration, such as changed SAML settings |
| Okta threat signals | security.threat.detected, security.attack.start, security.breached_credential.detected, security.session.detect_client_roaming, policy.auth_reevaluate.fail, user.risk.detect, user.risk.change | ThreatInsight, session roaming and Identity Threat Protection verdicts |
| Support access and logging | user.session.impersonation.grant, user.session.impersonation.initiate, system.log_stream.lifecycle.deactivate | Okta support impersonation and evidence pipeline tampering |
Detections to build
Help desk and factor takeover
- Reset then sign in from somewhere new:
user.mfa.factor.reset_alloruser.mfa.factor.deactivateon an account, followed within a few hours byuser.mfa.factor.activateand auser.session.startfrom an IP, ASN or device not seen for that user in 30 days. Weight it heavily when the target holds an admin role. This is the pattern in the help desk campaigns; see the Help Desk Social Engineering Incident Playbook and the MGM Resorts breach. - Push fatigue: several
user.mfa.okta_verify.deny_pushevents or faileduser.authentication.auth_via_mfaresults for one user in a short window, then a success. See the MFA Fatigue and Bypass Guide. - Phishing-resistant factor declined a phish:
user.authentication.auth_via_mfawith outcome FAILURE and the FastPass phishing reason means someone is running an adversary-in-the-middle page against that user. The credential is likely compromised even though the sign-in failed. See the AiTM Phishing Guide.
Privilege and configuration
- Any admin grant outside change control:
user.account.privilege.grant,group.privilege.grantandapp.oauth2.client.privilege.grant, enriched with the actor's session age and IP history. Super Administrator grants should page someone. - Policy weakening:
policy.rule.updateorpolicy.lifecycle.updatewherechangeDetailsshows a factor requirement removed, a network zone widened, or session lifetime increased;policy.rule.deactivateon any sign-on or MFA rule. - New identity provider: any
system.idp.lifecycle.createorupdate, and anyuser.authentication.auth_via_IDPif you do not use inbound federation. Okta's 2023 advisory describes attackers adding a second, attacker-controlled IdP and changing the username mapping to sign in as real users.
Session theft and access patterns
- Proxy and hosting sign-ins:
user.session.startoruser.session.access_admin_appwheresecurityContext.isProxyis true or the ASN belongs to a hosting provider, for any administrator. - Session reused from a new network: group events by
authenticationContext.externalSessionIdand alert when one session shows two client IPs in different ASNs or countries in a short period, alongside Okta's ownsecurity.session.detect_client_roaming. The Okta support system breach was spotted when a customer saw an admin sign-in attempt using a session cookie stolen from a support file. See the Session Hijacking and Cookie Theft Guide. - Password spraying: many
user.session.startfailures from one IP or ASN across many users, plussecurity.threat.detectedandsecurity.attack.startfrom ThreatInsight.
Non-human identities
- New SSWS token:
system.api_token.createcreates an unscoped token carrying its creator's admin rights. Alert on every creation by a human admin, and on creations by accounts with recent factor resets. - Token used from outside its zone:
system.api_token.request_outside_allowed_rangemeans a token with a network restriction was used from elsewhere, which is either a leak or a broken integration; both need action. - Token or service app behaving differently: profile
actor.typeof API token and OAuth client actors by event type and source IP; alert on a token that suddenly lists users or groups at volume, or calls admin APIs it has never called. ATT&CK v20 maps cloud account discovery (T1087.004) to this log source.
The NHI side of identity providers is discussed further in the ITDR Guide.
Mapping detections to ATT&CK and frameworks
| Detection | Key event types | ATT&CK v20 |
|---|---|---|
| Valid account sign-in from proxy or new ASN | user.session.start, user.authentication.sso | T1078.004 Cloud Accounts |
| Help desk factor reset abuse | user.mfa.factor.reset_all, user.account.reset_password | T1684 Social Engineering, T1098 Account Manipulation |
| Push fatigue | user.mfa.okta_verify.deny_push | T1621 Multi-Factor Authentication Request Generation |
| Session cookie replay | security.session.detect_client_roaming, session ID with two networks | T1539 Steal Web Session Cookie, T1550.004 Web Session Cookie |
| Sign-on policy weakened | policy.rule.update, policy.lifecycle.update | T1556.009 Conditional Access Policies |
| Rogue identity provider | system.idp.lifecycle.create, user.authentication.auth_via_IDP | T1556.007 Hybrid Identity, T1484.002 Trust Modification |
| Spraying and stuffing | Failed user.session.start, security.threat.detected | T1110.003 Password Spraying, T1110.004 Credential Stuffing |
| Admin role granted | user.account.privilege.grant, group.privilege.grant | T1098.003 Additional Cloud Roles |
| Users deactivated or locked out at scale | user.account.lock, user lifecycle deactivation | T1531 Account Access Removal |
| Log stream disabled | system.log_stream.lifecycle.deactivate | T1685.002 Disable or Modify Cloud Log |
In control frameworks the System Log supports NIST CSF 2.0 PR.PS-04 (log records generated and available), DE.CM-03 (monitoring personnel activity), DE.AE-02 and DE.AE-03 (analysis and correlation); NIST SP 800-53 Rev. 5 AU-2, AU-6, AU-11, AU-12 and SI-4, with AC-2 for account lifecycle monitoring; CIS Controls v8.1 Control 8 Audit Log Management; and ISO/IEC 27001:2022 Annex A 8.15 Logging and 8.16 Monitoring activities.
Rolling out and testing detections
- Baseline first (weeks 1 to 2): ingest 90 days of history with a bounded backfill, then switch to polling. Build per-user and per-token baselines of IP, ASN, country, device and event types.
- Deploy high-signal rules in alert mode (weeks 2 to 4): privilege grants, identity provider changes, policy rule changes, API token creation and log stream deactivation. These are rare enough to alert on directly.
- Tune behavioural rules in shadow mode (weeks 4 to 8): reset-then-new-sign-in, session roaming and proxy sign-ins run silently, with results reviewed weekly before alerts go to the SOC.
- Test with a preview tenant or test accounts: trigger each event deliberately (reset a test user's factors, create and revoke a test API token, add and remove a test IdP) and measure time to alert.
- Roll back safely: keep rules in version control so a noisy rule can be returned to shadow mode without losing its logic, and never disable a configuration-change rule without a replacement.
Decision guidance: small organisations with one Okta tenant and few admins can alert on every admin, policy and IdP event and review them by hand. Large organisations with many admins, automation and Okta Workflows need allowlists by actor and change ticket, and benefit from Identity Threat Protection signals (user.risk.detect, policy.auth_reevaluate.fail) as inputs rather than as the only detection. Choose log streaming when you run Splunk Cloud or an AWS event pipeline and want low latency; choose polling when you need a reliable system of record or a different SIEM. Many teams need both.
Metrics:
- Ingestion lag from
publishedto SIEM, by hour (target under 10 minutes). - Gaps detected per month in the Okta feed (target zero unexplained).
- Share of admin, policy and identity provider changes matched to a change ticket.
- Number of SSWS API tokens and their age, with the share replaced by scoped OAuth service apps.
- Time from a test factor reset to SOC alert in the quarterly exercise.
Common failure patterns
- Relying on Okta's 90 days: the investigation starts in month four and the initial access has aged out. Always hold your own copy.
- A deactivated stream nobody noticed: after two failed retries the stream stops, and because streams cannot replay, the gap is permanent unless a polling collector filled it.
- Collector on an admin's SSWS token: the token carries that admin's full rights, breaks when the admin leaves, and is itself an attractive target.
- Rules on
displayMessageortarget[0]: display text and target positions vary by event type; rules silently stop matching. - Treating ThreatInsight as the detection programme: Okta's signals catch spraying and known-bad IPs, not a convincing help desk call followed by a factor reset from a residential proxy.
- No correlation with the apps: the Okta session is the start of the story. Pivot on user and IP into the downstream application logs, for example the Microsoft 365 Unified Audit Log Guide for Detection.
Lessons from incidents
- Super Admin takeovers in 2023: Okta's cross-tenant impersonation advisory (31 August 2023, updated March 2024) describes help desk resets of Super Admin factors, sign-ins through anonymising proxies, privilege grants, removal of MFA from policies and a second IdP for impersonation. Each step produced a System Log event listed on this page; the gap was alerting, not logging.
- Stolen support session tokens: in the Okta support system breach a customer's own monitoring of admin sign-ins caught the stolen-cookie attempt, which is why session-to-network correlation for administrators is worth building even with phishing-resistant MFA in place.
Practitioner checklist
- Ingest the System Log with a polling collector using an OAuth service app scoped to
okta.logs.read. - Deduplicate on
uuid, order onpublished, and alert on feed gaps andsystem.log_stream.lifecycle.deactivate. - Retain at least 12 months of Okta events in the SIEM.
- Alert on every admin privilege grant, identity provider change, policy rule change and API token creation.
- Correlate factor resets with subsequent sign-ins from new IPs, ASNs or devices, prioritising administrators.
- Track sessions by
externalSessionIdand alert on network changes within a session. - Profile API token and OAuth client actors and alert on new APIs, volumes or source networks.
- Test each rule quarterly with deliberate events from test accounts and record time to alert.
- Replace remaining SSWS tokens with scoped OAuth service apps and track the count down.
Standards and references
- Okta: Management API OpenAPI specification (System Log, LogEvent)
- Okta Developer: System Log query
- Okta Developer: Event types catalogue
- Okta Help: About log streaming
- Okta Security: Cross-Tenant Impersonation, Prevention and Detection
- MITRE ATT&CK: Conditional Access Policies
- MITRE ATT&CK: Multi-Factor Authentication Request Generation
Related NHI Mgmt Group resources: Okta Security Hardening Guide · Identity Provider Tenant Compromise Playbook · ITDR Guide · Scattered Spider Threat Actor Profile · Detection Engineering Guide