Collect Okta logs
This document explains how to ingest Okta logs to Google Security Operations using the Okta API. The parser extracts system logs, handling both single events and batched events within a JSON array. It normalizes the data into the UDM format, mapping Okta fields to UDM equivalents, enriching the data with parsed user agents, geographical information, and authentication details, and generating security result events based on outcomes and risk information.
Before you begin
- Google SecOps instance
- Privileged access to Okta
How to configure Okta
To configure Okta SSO, complete the following tasks:
Create Okta Administrative user with read-only privileges
- Sign in to the Okta administrator console.
Create a Standard User.
- Go to Directory > People.
- Click Add person and complete the required fields.
Select Security > Administrators.
Click Add Administrator.
In the Administrator assignment by admin field, find the Standard User.
In the roles section, select Read-Only Administrator from the list.
Sign out from the administrator account.
Get API Key
- Sign in to the Okta Administrator Console with the read-only administrator user.
- Go to Security > API > Tokens.
- Click Create Token.
- Provide a meaningful name for the token.
- Provide the IP zone, where the API will be used (you can select any IP if you are not sure).
- Click Create Token.
- Copy the API key.
- Click OK, got it.
Set up feeds
To configure this log type, follow these steps:
- Go to SIEM Settings > Feeds.
- Click Add New Feed.
- Click the Cortex XDR feed pack.
Specify values for the following input parameters:
- Source Type: Third party API (recommended)
- Authentication HTTP header: Enter Okta API Key in the following format:
Authorization:<API_KEY>
. - API Hostname: Specify the domain name of your Okta host (for example,
<your-domain>.okta.com
). - Asset namespace: The asset namespace.
- Ingestion labels: The label applied to the events from this feed.
Advanced options
- Feed Name: A prepopulated value that identifies the feed.
- Asset Namespace: Namespace associated with the feed.
- Ingestion Labels: Labels applied to all events from this feed.
Click Create Feed.
For more information on configuring multiple feeds for different log types within this product family, see Configure feeds by product.
UDM Mapping Table
Log Field | UDM Mapping | Logic |
---|---|---|
actor.alternateId |
principal.user.email_addresses |
Extracted from actor.alternateId if it is an email address. If not an email address, used as principal.user.userid . |
actor.displayName |
principal.user.user_display_name |
Directly mapped. |
actor.id |
principal.user.product_object_id |
Directly mapped. |
actor.type |
principal.user.attribute.roles.name |
Directly mapped. |
authenticationContext.authenticationProvider |
security_result.detection_fields.value |
Directly mapped, with key authenticationProvider . |
authenticationContext.credentialProvider |
security_result.detection_fields.value |
Directly mapped, with key credentialProvider . |
authenticationContext.credentialType |
extensions.auth.mechanism |
Used to derive the authentication mechanism (OTP, USERNAME_PASSWORD, LOCAL). |
authenticationContext.externalSessionId |
network.parent_session_id |
Directly mapped. |
client.device |
principal.asset.type / additional.fields.value.string_value |
Mapped to principal.asset.type (WORKSTATION, MOBILE, ROLE_UNSPECIFIED) based on value. Also mapped as string value with key device in additional.fields . |
client.geographicalContext.city |
principal.location.city |
Directly mapped. |
client.geographicalContext.country |
principal.location.country_or_region |
Directly mapped. |
client.geographicalContext.geolocation.lat |
principal.location.region_latitude |
Directly mapped. |
client.geographicalContext.geolocation.lon |
principal.location.region_longitude |
Directly mapped. |
client.geographicalContext.postalCode |
additional.fields.value.string_value |
Directly mapped as string value with key Postal code in additional.fields . |
client.geographicalContext.state |
principal.location.state |
Directly mapped. |
client.ipAddress |
principal.ip , principal.asset.ip |
Directly mapped. |
client.userAgent.browser |
target.resource.attribute.labels.value |
Directly mapped, with key Browser . |
client.userAgent.os |
principal.platform |
Mapped to platform (LINUX, WINDOWS, MAC) based on value. |
client.userAgent.rawUserAgent |
network.http.user_agent , network.http.parsed_user_agent |
Directly mapped and parsed. |
client.zone |
additional.fields.value.string_value |
Directly mapped as string value with key zone in additional.fields . |
debugContext.debugData.behaviors |
security_result.description , security_result.detection_fields |
Directly mapped to description. Individual behaviors are extracted and added as detection fields. |
debugContext.debugData.changedAttributes |
security_result.detection_fields.value |
Directly mapped, with key changedAttributes . |
debugContext.debugData.clientAddress |
principal.ip , principal.asset.ip |
Directly mapped if request.ipChain and client.ipAddress are missing. |
debugContext.debugData.deviceFingerprint |
target.asset.asset_id |
Directly mapped, prefixed with device_finger_print: . |
debugContext.debugData.dtHash |
security_result.detection_fields.value |
Directly mapped, with key dtHash . |
debugContext.debugData.factor |
security_result.detection_fields.value |
Directly mapped, with key factor . |
debugContext.debugData.factorIntent |
security_result.detection_fields.value |
Directly mapped, with key factorIntent . |
debugContext.debugData.logOnlySecurityData.risk.reasons |
security_result.detection_fields.value |
Directly mapped, with key Risk Reasons . |
debugContext.debugData.privilegeGranted |
target.user.attribute.roles |
Split into individual privileges and added as roles with name and description. |
debugContext.debugData.pushOnlyResponseType |
security_result.detection_fields.value |
Directly mapped, with key pushOnlyResponseType . |
debugContext.debugData.pushWithNumberChallengeResponseType |
security_result.detection_fields.value |
Directly mapped, with key pushWithNumberChallengeResponseType . |
debugContext.debugData.requestUri |
extensions.auth.auth_details |
Directly mapped. |
debugContext.debugData.suspiciousActivityEventId |
security_result.detection_fields.value |
Directly mapped, with key suspiciousActivityEventId . |
debugContext.debugData.suspiciousActivityEventType |
security_result.detection_fields.value |
Directly mapped, with key suspiciousActivityEventType . |
debugContext.debugData.threatDetections |
security_result.detection_fields.value |
Directly mapped, with key threatDetections . |
debugContext.debugData.threatSuspected |
security_result.detection_fields.value , security_result.threat_status |
Mapped as a detection field with key threatSuspected . Used to derive threat status (ACTIVE or FALSE_POSITIVE). |
debugContext.debugData.url |
target.url |
Directly mapped. |
displayMessage |
security_result.summary |
Directly mapped. |
eventType |
metadata.product_event_type , metadata.event_type |
Directly mapped to product_event_type . Used to derive event_type (USER_LOGIN, USER_LOGOUT, USER_CHANGE_PASSWORD, USER_CHANGE_PERMISSIONS, USER_DELETION, GROUP_MODIFICATION, SETTING_MODIFICATION, SCHEDULED_TASK_ENABLE, RESOURCE_CREATION, USER_UNCATEGORIZED). |
legacyEventType |
security_result.detection_fields.value |
Directly mapped, with key legacyEventType . |
outcome.reason |
security_result.category_details |
Directly mapped. |
outcome.result |
security_result.action |
Mapped to action (ALLOW, CHALLENGE, BLOCK) based on value. |
published |
metadata.event_timestamp |
Parsed to timestamp. |
request.ipChain.n.geographicalContext |
intermediary.location |
Geographical context of intermediary IPs in the request chain. |
request.ipChain.n.ip |
intermediary.ip |
IP addresses of intermediaries in the request chain. |
securityContext.asNumber |
security_result.detection_fields.value |
Directly mapped, with key asNumber . |
securityContext.asOrg |
security_result.detection_fields.value |
Directly mapped, with key asOrg . |
securityContext.domain |
security_result.detection_fields.value |
Directly mapped, with key domain . |
securityContext.isp |
security_result.detection_fields.value |
Directly mapped, with key isp . |
securityContext.isProxy |
security_result.detection_fields.value |
Directly mapped, with key anonymized IP . |
target.n.alternateId |
target.user.email_addresses / target.user.userid |
If it is an email address, mapped to target.user.email_addresses . If not an email address, used as target.user.userid . |
target.n.detailEntry.clientAppId |
target.asset_id |
Directly mapped, prefixed with Client_app_id: . |
target.n.detailEntry.methodTypeUsed |
target.resource_ancestors.attribute.labels.value |
Directly mapped, with key methodTypeUsed when target type is AuthenticatorEnrollment. |
target.n.detailEntry.methodUsedVerifiedProperties |
target.resource_ancestors.attribute.labels.value |
Directly mapped, with key methodUsedVerifiedProperties when target type is AuthenticatorEnrollment. |
target.n.detailEntry.policyType |
target.resource_ancestors.attribute.labels.value |
Directly mapped, with key Policy Type . |
target.n.detailEntry.signOnModeType |
security_result.detection_fields.value |
Directly mapped, with key signOnModeType . |
target.n.displayName |
target.user.user_display_name / target.application / target.resource.name |
Mapped based on target type. |
target.n.id |
target.user.product_object_id / target.resource.product_object_id / target.resource_ancestors.product_object_id |
Mapped based on target type. |
target.n.type |
target.user.attribute.roles.name / target.resource.resource_subtype / target.resource_ancestors.resource_subtype |
Mapped based on target type. |
transaction.id |
network.session_id |
Directly mapped. |
transaction.type |
additional.fields.value.string_value |
Directly mapped as string value with key type in additional.fields . |
uuid |
metadata.product_log_id |
Directly mapped. |
N/A | metadata.vendor_name |
Set to Okta . |
N/A | metadata.product_name |
Set to Okta . |
N/A | extensions.auth.type |
Set to SSO . |
Need more help? Get answers from Community members and Google SecOps professionals.