Detection rules › Splunk

Okta New API Token Created

Status
production
Severity
medium
Group by
All_Changes.action, All_Changes.command, All_Changes.dest, All_Changes.object_category, All_Changes.result, All_Changes.src, All_Changes.user, _time, sourcetype
Author
Michael Haag, Mauricio Velazco, Splunk
Source
github.com/splunk/security_content

The following analytic detects the creation of a new API token within an Okta tenant. It uses OktaIm2 logs ingested via the Splunk Add-on for Okta Identity Cloud to identify events where the system.api_token.create command is executed. This activity is significant because creating a new API token can indicate potential account takeover attempts or unauthorized access, allowing an adversary to maintain persistence. If confirmed malicious, this could enable attackers to execute API calls, access sensitive data, and perform administrative actions within the Okta environment.

MITRE ATT&CK coverage

Rule body splunk

name: Okta New API Token Created
id: c3d22720-35d3-4da4-bd0a-740d37192bd4
version: 14
creation_date: '2022-12-19'
modification_date: '2026-05-13'
author: Michael Haag, Mauricio Velazco, Splunk
status: production
type: TTP
description: The following analytic detects the creation of a new API token within an Okta tenant. It uses OktaIm2 logs ingested via the Splunk Add-on for Okta Identity Cloud to identify events where the `system.api_token.create` command is executed. This activity is significant because creating a new API token can indicate potential account takeover attempts or unauthorized access, allowing an adversary to maintain persistence. If confirmed malicious, this could enable attackers to execute API calls, access sensitive data, and perform administrative actions within the Okta environment.
data_source:
    - Okta
search: |-
    | tstats `security_content_summariesonly` count max(_time) as lastTime, min(_time) as firstTime FROM datamodel=Change
      WHERE All_Changes.action=created
        AND
        All_Changes.command=system.api_token.create
      BY _time span=5m All_Changes.user
         All_Changes.result All_Changes.command sourcetype
         All_Changes.src All_Changes.action All_Changes.object_category
         All_Changes.dest
    | `drop_dm_object_name("All_Changes")`
    | `security_content_ctime(firstTime)`
    | `security_content_ctime(lastTime)`
    | `okta_new_api_token_created_filter`
how_to_implement: The analytic leverages Okta OktaIm2 logs to be ingested using the Splunk Add-on for Okta Identity Cloud (https://splunkbase.splunk.com/app/6553).
known_false_positives: False positives may be present. Tune Okta and tune the analytic to ensure proper fidelity. Modify risk score as needed.
references:
    - https://developer.okta.com/docs/reference/api/event-types/?q=security.threat.detected
    - https://splunkbase.splunk.com/app/6553
drilldown_searches:
    - name: View the detection results for - "$user$"
      search: '%original_detection_search% | search  user = "$user$"'
      earliest_offset: $info_min_time$
      latest_offset: $info_max_time$
    - name: View risk events for the last 7 days for - "$user$"
      search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$user$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
      earliest_offset: 7d
      latest_offset: "0"
finding:
    title: A new API token was created in Okta by [$user$]. Investigate further to determine if this was authorized.
    entity:
        field: user
        type: user
        score: 50
analytic_story:
    - Okta Account Takeover
    - Scattered Lapsus$ Hunters
asset_type: Okta Tenant
mitre_attack_id:
    - T1078.001
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: application
security_domain: access
tests:
    - name: True Positive Test
      attack_data:
        - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1098.001/okta_new_api_token_created/okta_new_api_token_created.log
          source: Okta
          sourcetype: OktaIM2:log
      test_type: unit

Stages and Predicates

Stage 1: tstats

| tstats `security_content_summariesonly` count max(_time) as lastTime, min(_time) as firstTime FROM datamodel=Change
  WHERE All_Changes.action=created
    AND
    All_Changes.command=system.api_token.create
  BY _time span=5m All_Changes.user
     All_Changes.result All_Changes.command sourcetype
     All_Changes.src All_Changes.action All_Changes.object_category
     All_Changes.dest

Stage 2: search

| `drop_dm_object_name("All_Changes")`

Stage 3: search

| `security_content_ctime(firstTime)`

Stage 4: search

| `security_content_ctime(lastTime)`

Stage 5: search

| `okta_new_api_token_created_filter`

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
All_Changes.actioneq
  • created
All_Changes.commandeq
  • "system.api_token.create"