Collect Okta User Context logs

Supported in:

This document explains how to collect Okta User Context logs by setting up a Google Security Operations feed using the Third party API.

Before you begin

Ensure that you have the following prerequisites:

  • A Google SecOps instance
  • Privileged access to Okta tenant or admin console
  • API token creation privileges in Okta

Configure IP allowlisting

Before creating the feed, you must allowlist Google SecOps IP ranges in your Okta firewall or network settings.

Get Google SecOps IP ranges

Add IP ranges to Okta User Context

  1. Sign in to the Okta Admin Console.
  2. Go to Security > Networks.
  3. Under IP Address Restrictions, click Edit.
  4. Add each Google SecOps IP range in CIDR notation to the trusted IP addresses.
  5. Click Save.

Configure Okta User Context API access

To enable Google SecOps to pull user context data, you need to create an API token with read permissions.

Create API token

  1. Sign in to the Okta Admin Console.
  2. Go to Security > API.
  3. Select the Tokens tab.
  4. Click Create Token.
  5. Provide the following configuration details:
    • Name: Enter a descriptive name (for example, Google SecOps Integration).
    • Description (optional): Enter a description.
  6. Click Create Token.

Record API credentials

After creating the API token, you'll receive the following credential:

  • API Token: Your API token value (for example, 00QCGr-1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1)

Required API permissions

The API token requires the following permissions in Okta:

Permission/Role Access Level Purpose
Read-Only Administrator Read Access user profile data
Super Administrator Read Complete access to all user data

Set up feeds

To configure a feed, follow these steps:

  1. Go to SIEM Settings > Feeds.
  2. Click Add New Feed.
  3. On the next page, click Configure a single feed.
  4. In the Feed name field, enter a name for the feed (for example, Okta User Context).
  5. Select Third party API as the Source type.
  6. Select Okta User Context as the Log type.
  7. Click Next.
  8. Specify values for the following input parameters:

    • Authentication HTTP header: Enter the authentication credentials in the following format:

      Authorization:SSWS your-api-token
      
      • For example: Authorization:SSWS 00QCGr-1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1
    • API Hostname: The fully qualified domain name of your Okta instance (e.g. example.okta.com, not any custom domain that may be configured).

      • For example: company.okta.com
    • Manager ID Reference Field: ID that is required when you use a non-Okta ID to reference managers (optional).

    • Asset namespace: The asset namespace.

    • Ingestion labels: The label to be applied to the events from this feed.

  9. Click Next.

  10. Review your new feed configuration in the Finalize screen, and then click Submit.

After setup, the feed begins to retrieve logs from the Okta User Context instance in chronological order.

Regional endpoints

Okta uses different API endpoints based on your organization's region:

Region Base URL / Hostname
US (Default) {org-name}.okta.com
EU (EMEA) {org-name}.okta-emea.com
APAC {org-name}.okta.com.au
Preview (Testing) {org-name}.oktapreview.com

Use the hostname that corresponds to your Okta instance region.

API rate limits

Okta API has the following rate limits:

  • Default rate limit: 600 requests per minute for most endpoints
  • System Log API: 60 requests per minute
  • User endpoints: 600 requests per minute

Google SecOps automatically handles rate limiting with exponential backoff. If you encounter issues, contact Okta support to increase your API limits.

UDM mapping table

Log Field UDM Mapping Logic
activated event.idm.entity.entity.labels If activated exists, its value is added as a key-value pair with the key "activated".
created event.idm.entity.entity.labels If created exists, its value is added as a key-value pair with the key "created".
profile.costCenter event.idm.entity.entity.labels If profile.costCenter exists, its value is added as a key-value pair with the key "costCenter".
profile.Function event.idm.entity.entity.labels If profile.Function exists, its value is added as a key-value pair with the key "Function".
statusChanged event.idm.entity.entity.labels If statusChanged exists, its value is added as a key-value pair with the key "statusChanged".
type.id event.idm.entity.entity.labels If type.id exists, its value is added as a key-value pair with the key "type_id".
profile.location event.idm.entity.entity.location.name Value taken from profile.location.
profile.AD_ObjectGUID event.idm.entity.entity.user.attribute.labels If profile.AD_ObjectGUID exists, its value is added as a key-value pair with the key "AD_ObjectGUID".
profile.ADpwdLastSet event.idm.entity.entity.user.attribute.labels If profile.ADpwdLastSet exists, its value is added as a key-value pair with the key "ADpwdLastSet".
profile.AFF_Code event.idm.entity.entity.user.attribute.labels If profile.AFF_Code exists, its value is added as a key-value pair with the key "AFF_Code".
profile.Desk_Location_WD event.idm.entity.entity.user.attribute.labels If profile.Desk_Location_WD exists, its value is added as a key-value pair with the key "Desk_Location_WD".
profile.Mailing_Address_WD event.idm.entity.entity.user.attribute.labels If profile.Mailing_Address_WD exists, its value is added as a key-value pair with the key "Mailing_Address_WD".
profile.Manager_UPN event.idm.entity.entity.user.attribute.labels If profile.Manager_UPN exists, its value is added as a key-value pair with the key "Manager_UPN".
profile.PRIVATE_CONF_Profile event.idm.entity.entity.user.attribute.labels If profile.PRIVATE_CONF_Profile exists, its value is added as a key-value pair with the key "PRIVATE_CONF_Profile".
profile.Region_WD event.idm.entity.entity.user.attribute.labels If profile.Region_WD exists, its value is added as a key-value pair with the key "Region_WD".
profile.Subsidiary_Company event.idm.entity.entity.user.attribute.labels If profile.Subsidiary_Company exists, its value is added as a key-value pair with the key "Subsidiary_Company".
profile.Telephone_Work event.idm.entity.entity.user.attribute.labels If profile.Telephone_Work exists, its value is added as a key-value pair with the key "Telephone_Work".
profile.Temp_WD_Primary_Email event.idm.entity.entity.user.attribute.labels If profile.Temp_WD_Primary_Email exists, its value is added as a key-value pair with the key "Temp_WD_Primary_Email".
profile.VMware_WS1_Username event.idm.entity.entity.user.attribute.labels If profile.VMware_WS1_Username exists, its value is added as a key-value pair with the key "VMware_WS1_Username".
profile.Work_Street_Address_WD event.idm.entity.entity.user.attribute.labels If profile.Work_Street_Address_WD exists, its value is added as a key-value pair with the key "Work_Street_Address_WD".
profile.Workato_WD_Primary_Email event.idm.entity.entity.user.attribute.labels If profile.Workato_WD_Primary_Email exists, its value is added as a key-value pair with the key "Workato_WD_Primary_Email".
profile.Workday_ID event.idm.entity.entity.user.attribute.labels If profile.Workday_ID exists, its value is added as a key-value pair with the key "Workday_ID".
profile.Worker_Type_WD event.idm.entity.entity.user.attribute.labels If profile.Worker_Type_WD exists, its value is added as a key-value pair with the key "Worker_Type_WD".
profile.businessUnit event.idm.entity.entity.user.attribute.labels If profile.businessUnit exists, its value is added as a key-value pair with the key "businessUnit".
profile.companyName event.idm.entity.entity.user.attribute.labels If profile.companyName exists, its value is added as a key-value pair with the key "companyName".
profile.contingentSupplierName event.idm.entity.entity.user.attribute.labels If profile.contingentSupplierName exists, its value is added as a key-value pair with the key "contingentSupplierName".
profile.conversationId event.idm.entity.entity.user.attribute.labels If profile.conversationId exists, its value is added as a key-value pair with the key "conversationId".
profile.distinguishedName event.idm.entity.entity.user.attribute.labels If profile.distinguishedName exists, its value is added as a key-value pair with the key "distinguishedName".
profile.division event.idm.entity.entity.user.attribute.labels If profile.division exists, its value is added as a key-value pair with the key "division".
profile.emailPrefix event.idm.entity.entity.user.attribute.labels If profile.emailPrefix exists, its value is added as a key-value pair with the key "emailPrefix".
profile.employeeType event.idm.entity.entity.user.attribute.labels If profile.employeeType exists, its value is added as a key-value pair with the key "employeeType".
profile.homePostalAddress event.idm.entity.entity.user.attribute.labels If profile.homePostalAddress exists, its value is added as a key-value pair with the key "homePostalAddress".
profile.isManager event.idm.entity.entity.user.attribute.labels If profile.isManager exists, its value is added as a key-value pair with the key "isManager".
lastLogin event.idm.entity.entity.user.attribute.labels If lastLogin exists, its value is added as a key-value pair with the key "lastLogin".
profile.leaveOfAbsence event.idm.entity.entity.user.attribute.labels If profile.leaveOfAbsence exists, its value is added as a key-value pair with the key "leaveOfAbsence".
profile.managerDn event.idm.entity.entity.user.attribute.labels If profile.managerDn exists, its value is added as a key-value pair with the key "managerDn".
profile.payGroup event.idm.entity.entity.user.attribute.labels If profile.payGroup exists, its value is added as a key-value pair with the key "payGroup".
profile.wdemployeeID event.idm.entity.entity.user.attribute.labels If profile.wdemployeeID exists, its value is added as a key-value pair with the key "wdemployeeID".
profile.zipCode event.idm.entity.entity.user.attribute.labels If profile.zipCode exists, its value is added as a key-value pair with the key "zipCode".
profile.userType event.idm.entity.entity.user.attribute.roles If profile.userType exists, its value is added to an array of roles.
profile.organization, profile.company event.idm.entity.entity.user.company_name Value taken from profile.organization, or profile.company if the former is not present.
profile.department event.idm.entity.entity.user.department Value taken from profile.department.
profile.email, profile.secondEmail, profile.login event.idm.entity.entity.user.email_addresses Values from profile.email, profile.secondEmail, and profile.login (if it's an email and not a duplicate) are merged into this field.
profile.employeeNumber event.idm.entity.entity.user.employee_id Value taken from profile.employeeNumber.
profile.firstName, profile.Preferred_First_Name event.idm.entity.entity.user.first_name Value taken from profile.firstName, or profile.Preferred_First_Name if the former is not present.
profile.EmployeeWorkGroup event.idm.entity.entity.user.group_identifiers Value taken from profile.EmployeeWorkGroup.
profile.HireDate, profile.hiredate event.idm.entity.entity.user.hire_date Value is parsed from profile.HireDate or profile.hiredate if the former is not present.
profile.lastName, profile.preferred_Last_Name event.idm.entity.entity.user.last_name Value taken from profile.lastName if either profile.lastName or profile.preferred_Last_Name exists.
lastLogin event.idm.entity.entity.user.last_login_time Value is parsed from lastLogin.
passwordChanged event.idm.entity.entity.user.last_password_change_time Value is parsed from passwordChanged.
profile.manager, profile.managerEmail, profile.managerId event.idm.entity.entity.user.managers Populated with an object containing user_display_name from profile.manager, email_addresses from profile.managerEmail, and employee_id from profile.managerId.
profile.city, profile.firstBaseCity event.idm.entity.entity.user.office_address.city Value taken from profile.city, or profile.firstBaseCity if the former is not present.
profile.countryCode, profile.country event.idm.entity.entity.user.office_address.country_or_region Value taken from profile.countryCode, or profile.country if the former is not present.
profile.streetAddress event.idm.entity.entity.user.personal_address.name Value taken from profile.streetAddress.
profile.state event.idm.entity.entity.user.personal_address.state Value taken from profile.state.
profile.primaryPhone, profile.mobilePhone, profile.mobile event.idm.entity.entity.user.phone_numbers Values from profile.primaryPhone, profile.mobilePhone, and profile.mobile are merged into this field.
profile.terminationDate, profile.terminationdate event.idm.entity.entity.user.termination_date Value is parsed from profile.terminationDate or profile.terminationdate if the former is not present.
profile.title event.idm.entity.entity.user.title Value taken from profile.title.
status event.idm.entity.entity.user.user_authentication_status Mapped from status: ACTIVE/RECOVERY/LOCKED_OUT/PASSWORD_EXPIRED -> ACTIVE; SUSPENDED -> SUSPENDED; DEPROVISIONED -> DELETED; otherwise UNKNOWN_AUTHENTICATION_STATUS.
profile.displayName event.idm.entity.entity.user.user_display_name Value taken from profile.displayName.
profile.samAccountName, profile.samaccountname, profile.login, profile.ldapUid event.idm.entity.entity.user.userid Populated with precedence: profile.samAccountName, profile.samaccountname, profile.login (if not an email), profile.ldapUid (if profile.login is not an email).
event.idm.entity.metadata.entity_type Set to USER.
id event.idm.entity.metadata.product_entity_id Value taken from id.
event.idm.entity.metadata.product_name Set to Identity Cloud.
event.idm.entity.metadata.vendor_name Set to Okta.

Need more help? Get answers from Community members and Google SecOps professionals.