Collect Okta logs
This document describes how you can collect Okta logs by setting up a Google Security Operations feed.
For more information, see Data ingestion to Google Security Operations.
An ingestion label identifies the parser which normalizes raw log data
to structured UDM format. The information in this document applies to the parser with the OKTA
ingestion label.
Configure Okta SSO
To configure Okta SSO, complete the following tasks:
Create read-only administrator user
- Sign in to the Okta SSO Administrator Console as an administrator.
- Create a Standard User. If you already have an existing standard user who you want to make a read-only administrator, proceed to the next step.
- Select Security > Administrators.
- Click Add Administrator.
- In the Grant administrator role to field, enter the username.
- In the Administrator roles section, select the Read-Only Administrator checkbox.
- Sign out from the administrator account.
Get API key
- Sign in to the Okta SSO Administrator Console with the read-only administrator created earlier.
- Select Security > API.
- Click Create Token.
- Enter the token name and click Create Token. The token value appears.
Copy the API key, which is required when you configure the Google Security Operations feed.
The API key cannot be recovered later and is stored in encrypted format after you close the window. If changes occur in the user or the privileges of the user who created the token, then the token is not valid. If the token is revoked or expired, then log collection is stopped until a new token is configured.
Click OK, got it.
Configure Okta ASA
To fetch Okta Advanced Server Access (ASA) audit events through the Okta system log API, integrate Okta ASA audit events with the Okta system log. To enable this integration, contact Okta support. For more information, see the Okta help center.
Configure a feed in Google Security Operations to ingest Okta logs
- Go to SIEM Settings > Feeds.
- Click Add New.
- Enter a unique name for the Field Name.
- Select Third party API as the Source Type.
- Select Okta as the Log Type.
- Click Next.
- Configure the following mandatory input parameters:
- Authentication HTTP Header: specify credentials that authenticate a user agent with a server, giving access to a protected resource.
- API Hostname: specify the domain name or IP address of the host that serves the API.
- Click Next and then click Submit.
For more information about Google Security Operations feeds, see Google Security Operations feeds documentation. For information about requirements for each feed type, see Feed configuration by type.
If you encounter issues when you create feeds, contact Google Security Operations support.
Field mapping reference
This parser handles Okta system logs in JSON format, extracting fields from both Stackdriver-wrapped logs and raw Okta logs. It normalizes the data into the UDM format, focusing on identity and access management events, including logins, logouts, permission changes, and security threats, while also handling various authentication types and enriching the data with geographical context and user agent information. The parser also extracts security-related details like risk reasons, threat indicators, and suspicious activity information.
UDM Mapping Table
Log Field | UDM Mapping | Logic |
---|---|---|
actor.alternateId |
principal.user.email_addresses / principal.user.userid |
If the alternateId field is a valid email address, the username part is mapped to principal.user.userid and the full email address is added to the principal.user.email_addresses list. If it's not a valid email, the entire value is mapped to principal.user.userid . |
actor.displayName |
principal.user.user_display_name |
Direct mapping. |
actor.id |
principal.user.product_object_id |
Direct mapping. |
actor.type |
principal.user.attribute.roles.name |
Direct mapping. |
authenticationContext.authenticationProvider |
security_result.detection_fields.value where key is "authenticationProvider" |
Direct mapping as a detection field. |
authenticationContext.credentialProvider |
security_result.detection_fields.value where key is "credentialProvider" |
Direct mapping as a detection field. |
authenticationContext.credentialType |
extensions.auth.mechanism |
Used to derive the authentication mechanism. "OTP" or "SMS" becomes "OTP", "PASSWORD" becomes "USERNAME_PASSWORD", "IWA" or eventType "user.authentication.auth_via_AD_agent" becomes "LOCAL". |
authenticationContext.externalSessionId |
network.parent_session_id |
Direct mapping. |
client.device |
principal.asset.type / additional.fields.value.string_value where key is "device" |
If the value is "Mobile", it maps to "MOBILE". If "Computer", it maps to "WORKSTATION". If "Unknown", it maps to "ROLE_UNSPECIFIED". Also added as an additional field. |
client.geographicalContext.city |
principal.location.city |
Direct mapping. |
client.geographicalContext.country |
principal.location.country_or_region |
Direct mapping. |
client.geographicalContext.geolocation.lat |
principal.location.region_latitude |
Direct mapping. |
client.geographicalContext.geolocation.lon |
principal.location.region_longitude |
Direct mapping. |
client.geographicalContext.postalCode |
additional.fields.value.string_value where key is "Postal code" |
Direct mapping as an additional field. |
client.geographicalContext.state |
principal.location.state |
Direct mapping. |
client.ipAddress |
principal.ip / principal.asset.ip |
Direct mapping. If not present, the parser attempts to extract it from other fields like request.ipChain.0.ip or debugContext.debugData.clientAddress . |
client.userAgent.browser |
target.resource.attribute.labels.value where key is "Browser" |
Direct mapping as a label. |
client.userAgent.os |
principal.platform |
If the value contains "Linux", it maps to "LINUX". If "windows", it maps to "WINDOWS". If "mac" or "ios", it maps to "MAC". |
client.userAgent.rawUserAgent |
network.http.user_agent |
Direct mapping. Also parsed and stored in network.http.parsed_user_agent . |
client.zone |
additional.fields.value.string_value where key is "zone" |
Direct mapping as an additional field. |
debugContext.debugData.behaviors |
security_result.description |
Direct mapping. Individual behaviors are also extracted as separate detection fields. |
debugContext.debugData.changedAttributes |
security_result.detection_fields.value where key is "changedAttributes" |
Direct mapping as a detection field. |
debugContext.debugData.clientAddress |
principal.ip / principal.asset.ip |
Used as a fallback if client.ipAddress and request.ipChain.0.ip are not present. |
debugContext.debugData.deviceFingerprint |
target.asset.asset_id |
Prefixed with "device_finger_print:" and then mapped. |
debugContext.debugData.dtHash |
security_result.detection_fields.value where key is "dtHash" |
Direct mapping as a detection field. |
debugContext.debugData.factor |
security_result.detection_fields.value where key is "factor" |
Direct mapping as a detection field. |
debugContext.debugData.factorIntent |
security_result.detection_fields.value where key is "factorIntent" |
Direct mapping as a detection field. |
debugContext.debugData.logOnlySecurityData.risk.reasons |
security_result.detection_fields.value where key is "Risk Reasons" |
Direct mapping as a detection field. |
debugContext.debugData.privilegeGranted |
target.user.attribute.roles.name / target.user.attribute.roles.description |
Each privilege is added as a separate role with both name and description set to the privilege value. |
debugContext.debugData.pushOnlyResponseType |
security_result.detection_fields.value where key is "pushOnlyResponseType" |
Direct mapping as a detection field. |
debugContext.debugData.pushWithNumberChallengeResponseType |
security_result.detection_fields.value where key is "pushWithNumberChallengeResponseType" |
Direct mapping as a detection field. |
debugContext.debugData.requestId |
network.session_id |
Direct mapping. |
debugContext.debugData.requestUri |
extensions.auth.auth_details / target.url |
Direct mapping. |
debugContext.debugData.suspiciousActivityEventId |
security_result.detection_fields.value where key is "suspiciousActivityEventId" |
Direct mapping as a detection field. |
debugContext.debugData.suspiciousActivityEventType |
security_result.detection_fields.value where key is "suspiciousActivityEventType" |
Direct mapping as a detection field. |
debugContext.debugData.threatDetections |
security_result.detection_fields.value where key is "threatDetections" |
Direct mapping as a detection field. |
debugContext.debugData.threatSuspected |
security_result.detection_fields.value where key is "threatSuspected" |
Direct mapping as a detection field. Also used to determine security_result.threat_status . If true, the status is "ACTIVE", otherwise "FALSE_POSITIVE". |
debugContext.debugData.url |
target.url |
Direct mapping. |
displayMessage |
security_result.summary |
Direct mapping. |
eventType |
metadata.product_event_type |
Direct mapping. Also used to determine metadata.event_type (see logic below). |
legacyEventType |
security_result.detection_fields.value where key is "legacyEventType" |
Direct mapping as a detection field. |
outcome.reason |
security_result.category_details |
Direct mapping. |
outcome.result |
security_result.action |
"SUCCESS" or "ALLOW" becomes "ALLOW", "CHALLENGE" becomes "CHALLENGE", "FAILURE", "DENY", "SKIPPED", or "RATE_LIMIT" becomes "BLOCK". |
published |
metadata.event_timestamp |
Converted to a timestamp. |
request.ipChain.0.geographicalContext.* |
principal.location.* |
Geographical context of the first IP in the chain is mapped to the principal's location. |
request.ipChain.0.ip |
principal.ip / principal.asset.ip |
Direct mapping. |
request.ipChain.1.geographicalContext.* |
intermediary.location.* |
Geographical context of the second IP in the chain is mapped to the intermediary location. |
request.ipChain.1.ip |
intermediary.ip |
Direct mapping. |
securityContext.asNumber |
security_result.detection_fields.value where key is "asNumber" |
Direct mapping as a detection field. |
securityContext.asOrg |
security_result.detection_fields.value where key is "asOrg" |
Direct mapping as a detection field. |
securityContext.domain |
security_result.detection_fields.value where key is "domain" |
Direct mapping as a detection field if the value is not ".". |
securityContext.isp |
security_result.detection_fields.value where key is "isp" |
Direct mapping as a detection field. |
securityContext.isProxy |
security_result.detection_fields.value where key is "anonymized IP" |
Direct mapping as a detection field. |
target.0.alternateId |
target.user.email_addresses / target.user.userid |
Logic similar to actor.alternateId . |
target.0.detailEntry.clientAppId |
target.asset_id |
Prefixed with "Client_app_id:" and then mapped. |
target.0.displayName |
target.user.user_display_name / target.application / target.resource.name |
Mapped based on target.0.type . |
target.0.id |
target.user.product_object_id / target.resource.product_object_id |
Mapped based on target.0.type . |
target.0.type |
target.user.attribute.roles.name / target.resource.resource_subtype |
Mapped based on the value. Also used to determine the mapping of other target.0 fields. |
target.1.alternateId |
target.user.email_addresses / target.user.userid |
Logic similar to actor.alternateId . |
target.1.detailEntry.clientAppId |
target.asset_id |
Prefixed with "Client_app_id:" and then mapped. |
target.1.displayName |
target.user.user_display_name / target.resource.name |
Mapped based on target.1.type . |
target.1.id |
target.user.product_object_id / target.resource.product_object_id |
Mapped based on target.1.type . |
target.1.type |
target.user.attribute.roles.name / target.resource.resource_subtype |
Mapped based on the value. Also used to determine the mapping of other target.1 fields. |
target.2.alternateId target.2.displayName target.2.id target.2.type transaction.id |
network.session_id |
Direct mapping. |
transaction.type |
additional.fields.value.string_value where key is "type" |
Direct mapping as an additional field. |
uuid |
metadata.product_log_id |
Direct mapping. |
N/A | metadata.event_type |
Determined by eventType . See the parser code for the full mapping logic. Some key mappings include: "user.authentication.sso", "user.authentication.auth_via_mfa", "user.session.start" map to "USER_LOGIN"; "user.session.end" maps to "USER_LOGOUT"; "user.account.reset_password" maps to "USER_CHANGE_PASSWORD"; "application.user_membership.update" maps to "USER_CHANGE_PERMISSIONS"; "security.threat.detected" maps to "USER_UNCATEGORIZED"; "system.import.user.delete" maps to "USER_DELETION"; "policy.rule.update" maps to "SETTING_MODIFICATION"; "group.user_membership.remove" maps to "GROUP_MODIFICATION". Many other eventType values map to "USER_UNCATEGORIZED". |
N/A | metadata.log_type |
Set to "OKTA". |
N/A | metadata.product_name |
Set to "Okta". |
N/A | metadata.vendor_name |
Set to "Okta". |
N/A | extensions.auth.type |
Set to "SSO". |
Changes
2024-05-16
- If "is_alert" is true and "is_significant" is true, then set "security_result.alert_state" as "ALERTING".
2024-03-05
- Updated "security_result.action" field to reflect whether the traffic was allowed or blocked.
2024-02-16
- Bug-Fix:
- When "target.0.type" is "User" or "AppUser", then mapped "target.0.alternateId" to "target.user.userid".
- When "target.1.type" is "User" or "AppUser", then mapped "target.1.alternateId" to "target.user.userid".
2023-12-14
- Mapped "securityContext.asNumber" to "security_result.detection_fields".
- Mapped "legacyEventType" to "security_result.detection_fields".
- Added "conditional_check" before setting "metadata.event_type".
2023-06-28
- Mapped complete value of "debugContext.debugData.suspiciousActivityEventType" to "security_result.detection_fields".
- Mapped complete value of "debugContext.debugData.logOnlySecurityData.behaviors.New Device" to "security_result.detection_fields".
2023-06-09
- The field "debugContext.debugData.deviceFingerprint" is mapped to "target.asset.asset_id".
- Mapped complete value of "debugContext.debugData.risk.reasons" to "security_result.detection_fields".
2023-05-17
- The field 'authenticationContext.externalSessionId' is mapped to 'network.parent_session_id'.
- The field 'debugContext.debugData.pushOnlyResponseType' is mapped to 'security_result.detection_fields.key/value'.
- The field 'debugContext.debugData.factor' is mapped to 'security_result.detection_fields.key/value'.
- The field 'debugContext.debugData.factorIntent' is mapped to 'security_result.detection_fields.key/value'.
- The field 'debugContext.debugData.pushWithNumberChallengeResponseType' is mapped to 'security_result.detection_fields.key/value'.
- The field 'debugContext.debugData.dtHash' is mapped to 'security_result.detection_fields.key/value'.
- The field 'client.userAgent.rawUserAgent' is mapped to 'network.http.user_agent'.
- Changed the mapping from 'ALLOW_WITH_MODIFICATION' to enum value 'CHALLENGE' under 'security_result.action'.
- For the eventType 'system.api_token.create', changed metadata.event_type from 'USER_UNCATEGORIZED' to 'RESOURCE_CREATION'.
2023-04-28
- Bug-Fix:
- Modified mapping for "security_result.threat_status" to "ACTIVE" when "debugContext.debugData.threatSuspected" is "true" else mapped to "FALSE_POSITIVE".
2023-03-24
- Mapped "logOnlySecurityData" fields to "security_result.detection_fields".
- Additionally, resolved parsing error by adding "DEFERRED" to action list.
2023-04-11
- Remapped the fields which are mapped to "http.user_agent" to "http.parsed_user_agent".
- Mapped "target.displayName" to "target.resource_ancestors.name".
- Mapped "targetfield.detailEntry.methodTypeUsed" to "target.resource_ancestors.attribute.labels".
- Mapped "targetfield.detailEntry.methodUsedVerifiedProperties" to "target.resource_ancestors.attribute.labels".
2023-02-20
- Changed "metadata.event_type" from "USER_LOGIN" to "STATUS_UPDATE" where "eventType" is "user.authentication.auth_via_AD_agent"
2022-12-14
- Mapped "debugContext.debugData.changedAttributes" to "security_result.detection_fields".
- Added null check for "detail.actor.alternateId".
2022-11-17
- The field "target[n].alternateId" is mapped to "target.resource.attribute.labels".
- The field "detail.target.0.alternateId" is mapped to "target.resource.attribute.labels".
2022-11-08
- Bug-fix:
- Added condition for proper email check for field "user_email".
- Added check for field "Action1" not in "RATE_LIMIT".
- Added null, unknown check for "actor.displayName".
2022-11-04
- Added support for logs having multiple events.
2022-10-15
- "signOnModeType" mapped to "security_result.detection_fields".
- "authenticationProvider" mapped to "security_result.detection_fields".
- "credentialProvider" mapped to "security_result.detection_fields".
- "device" mapped to "additional.fields".
- "zone" mapped to "additional.fields".
- "type" mapped to "additional.fields".
2022-10-14
- Bug-fix:
- Added conditional check for 'principal.user.email_addresses' and 'target.user.email_addresses'.
- Added grok to check for valid ip_address for the field 'request.ipChain.0.ip' mapped to 'principal.ip'.
- Added on_error condition for the field 'debugContext.debugData.url' mapped to 'target.url'.
2022-10-03
- Mapped "client.userAgent.os" to "principal.platform".
- Mapped "client.device" to "principal.asset.type".
- Mapped "anonymized IP" (hardcoded string) to security_result.detection_fields.key where 'securityContext.isProxy' value to corresponding security_result.detection_fields.value.
2022-09-16
- 'securityContext.asOrg' mapped to 'security_result.category_details'.
- 'securityContext.isProxy' mapped to 'security_result.detection_fields'.
- 'securityContext.domain' mapped to 'security_result.detection_fields'.
- 'securityContext.isp' mapped to 'security_result.detection_fields'.
- 'debugContext.debugData.risk.level' mapped to 'security_result.severity'.
- 'debugContext.debugData.risk.reasons' mapped to 'security_result.detection_fields'.
2022-08-12
- the newly ingested logs have been parsed and mapped to following fields:
- 'detail.uuid' mapped to 'metadata.product_log_id'.
- 'detail.eventType' mapped to 'metadata.product_event_type'
- 'detail.actor.id' mapped to 'principal.user.product_object_id'.
- if 'detail.actor.alternateId' mapped to 'principal.user.userid' else
- 'detail.actor.alternateId' mapped to 'principal.user.email_addresses'.
- 'detail.actor.displayName' mapped to 'principal.user.user_display_name'.
- 'detail.actor.type' mapped to '.principal.user.attribute.roles'.
- 'detail.client.ipChain.0.ip' mapped to 'principal.ip'.
- 'detail.client.ipChain.0.geographicalContext.state' mapped to 'principal.location.state'.
- 'detail.client.ipChain.0.geographicalContext.city' mapped to 'principal.location.city'.
- 'detail.client.ipChain.0.geographicalContext.country' mapped to 'principal.location.country_or_region'.
- 'detail.debugContext.debugData.requestUri' mapped to 'target.url'.
- 'detail.target.0.type' mapped to 'target.resource.resource_subtype'.
- 'detail.target.0.id' mapped to 'target.resource.resource.product_object_id'.
- 'detail.target.0.displayName' mapped to 'target.resource.resource_subtype'.
- 'detail.target.0.detailEntry.policyType' mapped to 'target.resource_ancestors.attribute.labels'.
- 'detail.outcome.reason' mapped to 'security_result.category_details'.
- 'detail.debugContext.debugData.threatSuspected' mapped to 'security_result.detection_fields'.
- 'detail.displayMessage' mapped to 'security_result.summary'.
- 'detail.outcome.result' mapped to 'security_result.action'.
- 'detail.severity' mapped to 'security_result.severity'.
- 'detail.transaction.id' mapped to 'network.session_id'.
- 'detail.debugContext.debugData.requestUri' mapped to 'extensions.auth.auth_details'.
2022-07-08
- Modified mapping for "actor.type" from "principal.user.role_name" to "principal.user.attribute.roles".
- Modified mapping for "target.0.type" from "target.user.role_name" to "target.user.attribute.roles".
- Modified mapping for "target.1.type" from "target.user.role_name" to "target.user.attribute.roles".
2022-06-15
- Enhancement-
- for "target.0.type" == "Token".
- Mapped "target.0.detailEntry.clientAppId" to "target.asset_id".
- Added conditional check for the field 'transaction.id' mapped to the UDM field 'network.session_id'.
2022-06-03
- Enhancement-
- Mapped debugContext.debugData.privilegeGranted to target.user.attribute.roles.name additionally.
- Mapped debugContext.debugData.requestUri to extensions.auth.auth_details.
- Mapped debugContext.debugData.suspiciousActivityEventId, debugContext.debugData.threatDetections, debugContext.debugData.threatSuspected to security_result.detection_fields.
2022-03-22
- Enhancement-
- debugContext.debugData.behaviors mapped to security_result.description.
- debugContext.debugData.threatSuspected mapped to security_result.threat_status.
- debugContext.debugData.risk mapped to security_result.severity.