As organizations continue to shift to cloud-based or entirely cloud-native environments, incident responders now have the challenging task of researching and deciphering how each SaaS vendor can be both attacked and investigated. In this series, Mitiga incident responders share knowledge we’ve gained from our investigations and threat hunting to provide insight into the key log fields to use when investigating SaaS compromises.

For part one of this series, we will focus on Okta System Logs. The Okta System Log “records system events that are related to your organization in order to provide an audit trail that can be used to understand platform activity and to diagnose problems.1" While Okta System Logs give incident responders an opportunity for both forensic investigation and detection, there are various pitfalls and issues that they might also encounter. This blog will highlight those challenges, offer strategies to overcome them, and pseudocode to help you track sessions in Okta effectively. You can implement the pseudocode provided as an investigation function or use it as a query during an investigation.

Okta System Log Key Fields

The table below provides a list of important fields for tracking sessions, hunting, and investigating in Okta. As with many SaaS vendors, logs can change, new research may be conducted, and investigative techniques must adapt accordingly. Make sure to check back periodically for updates to this table and feel free to reach out to us if we can improve its content. 

While most of these fields are accurate and perform as expected, we have found that the debugContext.debugData.risk and debugContext.debugData.deviceFingerprint fields have inaccuracies and limitations that investigators and detection engineers should be aware of. Even if you are familiar with Okta logs, we recommend reviewing the notes on these two specific fields to understand the highlighted challenges.

Field Description Sample Value
published Action timestamp 2024-01-10T07:32:48.742Z
actor.alternateId This reflects the actor's identity, often their email, dependent on the 'actor_type'. For 'User', it's the user's email; 'PublicClientAppEntity' defaults to 'unknown'; 'SystemPrincipal' is either '' or ''; 'Event Hook' remains unset. 'PublicClientApp' links to ''. 0oae2szv32xaTYRst2p7
unknown This reflects the actor's identity, identified by an Okta-specific identifier. 0oae2XXXXXXXXXXst2p7
actor.type Okta actor type. PublicClientApp
Event Hook
client.device Client device type. unknown
client.ipAddress Client request IP address: either IPv4 or IPv6 format.
client.userAgent.rawUserAgent User agent of the web request used by the actor to perform an action. Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36
client.userAgent.browser Browser family identified by Okta from the user agent. FIREFOX
unknown Client zone name, based on client.ipAddress subnet range. This is organization specific as defined by organizations admins. null
<Custom Zone name> City determined by Okta based on client.ipAddress. Charlestown
New York Country determined by Okta based on client.ipAddress. United States
eventType Event type published, as detailed in Okta's documentation: Okta Event Types.2
displayMessage Event display message: A human-readable description of the eventType. Send user MFA enrollment notification email
target.type Refers to the zero or more types that the action targets. ["AuthenticatorMethod","AuthenticatorMethod","AppInstance"]
target.displayName Target.type refers to the zero or more types that the action targets. Target.type and Target.DisplayName values are ordered. Think of Target.type as the key and Target.DisplayName as the corresponding values. ["Password","Okta Verify","Okta Dashboard"]
outcome.result The result of the eventType. SUCCESS
outcome.reason Reason for the result. Null if it was successful, otherwise it is populated with reason. Sign-on policy evaluation resulted in AUTHENTICATED
no_matching_policy The ID of a series of actions, authenticated or not, that identifies events occurring together, such as a request to Okta's servers. The value will be identical to debugContext.debugData.requestId or debugContext.debugData.emailRequestId. f938cb7b727fe8XXXXXXXXXXXXXXXXXX
securityContext.asOrg The organization, ASN, associated with the client's IP address from which the eventType was initiated. cox communications
amazon technologies inc.
authenticationContext.externalSessionId This ID is set following successful authentication and is unique per user session. Useful for correlating events that occurred within the same user session. 102XXXXXXXX
debugContext The debugContext field provides additional information for certain types of events where the default fields are insufficient to adequately describe the operations performed by the event. It contains valuable sub-fields, some of which have been documented in this sheet. The size and content of debugContext depend on the event type. { debugData: { behaviors: "{New Geo-Location=NEGATIVE, New Device=BAD_REQUEST, New IP=NEGATIVE, New State=NEGATIVE, New Country=NEGATIVE, Velocity=NEGATIVE, New City=NEGATIVE}", requestId: "3513cb19071ddcXXXXXXXXXXXXXXXXXX", dtHash: "1b9cdd35a8d4f0708072ae6957324c9adf8XXXXXXXXXXXXXXXXXX", risk: "{reasons=Anomalous Device, level=HIGH}", requestUri: "/api/v1/authn", threatSuspected: "false", url: "/api/v1/authn?" } }
debugContext.debugData.risk Okta performs a risk assessment for actions performed and assigns the risk level to this field. For instance, the risk level for a sign-in event might be determined by factors such as anomalous location, anomalous device, suspected threats based on Okta ThreatInsight detection, or missing cookies.

While this field provides valuable information, it should be interpreted with caution. At the time of writing historical examination revealed issues, such as the error-prone nature of anomalous device detection due to limitations in device fingerprinting.

Additionally, there may be bugs affecting anomalous location detection, where an IP address may appear to be from a new country despite being associated with a known city.
{reasons=Anomalous Location, Anomalous Device, level=HIGH}
debugContext.debugData.behaviours This field provides insight into the risk assessment performed by Okta, which is recorded as boolean assignments (True or False). {New Geo-Location=UNKNOWN, New Device=UNKNOWN, New IP=UNKNOWN, New State=UNKNOWN, New Country=UNKNOWN, Velocity=UNKNOWN, New City=UNKNOWN}
{New Geo-Location=NEGATIVE, New Device=NEGATIVE, New IP=NEGATIVE, New State=NEGATIVE, New Country=NEGATIVE, Velocity=NEGATIVE, New City=NEGATIVE}
debugContext.debugData.factor Authentication factor used for the action. This field is only set for "user.authentication.auth_via_mfa" events. SECURITY_QUESTION
debugContext.debugData.factorIntent The initial actor intent that triggered the factor. This field is present for "user.authentication.verify" and "user.authentication.auth_via_mfa" events. AUTHENTICATION
debugContext.debugData.requestId The ID of a request, which identifies events occurring together as part of an operation (e.g., a request to Okta's servers). The value will be identical to or debugContext.debugData.emailRequestId. It's recommended to use f938cb7b727fe8XXXXXXXXXXXXXXXXXX
debugContext.debugData.emailRequestId If an action results in a "" event, the value of this event is recorded in this field. The value will be identical to or debugContext.debugData.requestId. f938cb7b727fe8XXXXXXXXXXXXXXXXXX
debugContext.debugData.authnRequestId Unique authentication request ID. The value may or may not be identical to, debugContext.debugData.requestId, or debugContext.debugData.emailRequestId. f938cb7b727fe8XXXXXXXXXXXXXXXXXX
debugContext.debugData.dtHash Based on available documentation, this field appears to represent the device token hash. While the exact calculation method is unclear, it seems to be a SHA256 hash. Overlap across multiple user accounts is possible. This field serves as a good indicator when targeting a single account to identify potential theft of session tokens. 9def5cf1c6bbb852021970f8a60cd176810XXXXXXXXXXXXXXXXXX
debugContext.debugData.deviceFingerprint This field is intended to represent a unique device ID. However, significant overlap is observed, and there is no clear pattern regarding its calculation.

Documentation lacks clarity on the calculation method, suggesting that different tools may set it differently. It could be based solely on the user agent or utilize other browser-based fingerprinting techniques, such as cookies, device information, and IPs.

When used for investigation, it's important to note the common overlaps in this field. While it might appear that multiple users are using the same device, caution is advised. It's recommended to combine this information with other indicators to track malicious activity.
debugContext.debugData.deviceCategory This field is set for system.push.send_factor_verify_push events. It specifies the device type where the MFA response was received/responded to. SmartPhone_Android

Session Tracking

In the event of a compromise to an Okta account, it's recommended to use the fields to track all actions performed by the threat actor in a session, covering both authenticated and pre-authentication stages, as well as actions initiated by the Okta system itself. 

  1. authenticationContext.externalSessionId
  3. debugContext.debugData.emailRequestId
  4. debugContext.debugData.authnRequestId

To ensure a thorough investigation, it's also advised to identify all unique identifiers within these fields associated with confirmed malicious events and use them as pivot points for further analysis. It's important to recognize that and debugContext.debugData.emailRequestId will always share identical values, whereas the debugContext.debugData.authnRequestId might only occasionally match.

Upon identifying any specific values assigned to these fields, we recommend employing the following filter logic for isolating malicious activity:

  • Match malicious authenticationContext.externalSessionId values with authenticationContext.externalSessionId.
    • OR
  • Match malicious values of, debugContext.debugData.emailRequestId, and debugContext.debugData.authnRequestId to, debugContext.debugData.emailRequestId, or debugContext.debugData.authnRequestId

Example pseudo code:

# Define lists of known malicious session and transaction/request IDs

malicious_sessions = ["idxXXXXXXXX"]
malicious _request_ids = [

# Begin filtering process on Okta data
FOR EACH record IN okta_delta
    IF record's externalSessionId IS IN malicious_sessions
        OR record's transactionId IS IN malicious _request_ids
        OR record's emailRequestId IS IN malicious _request_ids
        OR record's authnRequestId IS IN malicious _request_ids
        MARK record as malicious
    END IF

Those who are fortunate may not be compromised and only need to review logs for detection engineering. However, during an investigation of a compromise, every piece of information is crucial in building a comprehensive picture. If there are issues with certain fields that you are unaware of, it can significantly sidetrack the investigation and impact the severity assessment of the incident.

We aim to continuously update this page as changes occur, providing the security community with thorough reference materials and insights necessary for confident investigations. We plan to cover other vendors and log sources in the upcoming months, ensuring you have the documentation needed to respond to threats effectively.


June 26, 2024

Don't miss these stories:

How Behavioral Detections Aid Healthcare Security

Healthcare organizations face unique cybersecurity challenges due to their hybrid IT (information technology) environments, sensitive data, and resource constraints.

Using Gen AI for Cloud Threat Detection and Investigation

AI-driven cloud attacks require and AI-driven response. Learn how AI can automate threat intelligence, accelerate response times, and simplify investigations.

Automating AWS Infrastructure Creation with Crossplane and GitOps

A while back, I started migrating my CD to a full GitOps process.