Query Details

Open AI Config To Abuse Chain

Query

id: c3d4e5f6-3333-4ccc-9003-0123456789ad
name: OpenAI - Privileged config change followed by abuse signal
description: |
  Correlates a privileged OpenAI configuration or credential change
  (org settings, role change, key / service-account / project creation,
  member invite) with a downstream abuse signal from the same actor
  within 24 hours: a model request that hit a content filter, was
  truncated for length, or returned no finish reason.

  Ported from the Microsoft 365 Copilot "Config-to-abuse chain" rule.
  The actor join key here is ActorSession.user.email (audit side) matched
  to AdditionalFields.input_user (runtime side). That mapping is
  tenant-specific - OpenAI's 'user' request parameter is only a reliable
  bridge if your callers set it to the same identity. Adjust or remove
  the join predicate to fit your instrumentation.
severity: High
requiredDataConnectors:
- connectorId: OpenAI
  dataTypes:
  - OpenAIAuditLogs_CL
  - ASimAgentEventLogs
queryFrequency: PT1H
queryPeriod: P1D
triggerOperator: gt
triggerThreshold: 0
enabled: true
tactics:
- Persistence
- DefenseEvasion
- Execution
relevantTechniques:
- T1098
- T1556
- T1059
query: |
  let window = 1d;
  let configChanges =
      OpenAIAuditLogs
      | where TimeGenerated > ago(window)
      | where EventType has_any (
            "settings", "organization.updated", "logging", "retention",
            "role", "user.added", "invite", "service_account.created",
            "api_key.created", "project.created")
      | extend ActorEmail = tolower(tostring(ActorSession.user.email))
      | where isnotempty(ActorEmail)
      | project
          ConfigTime = TimeGenerated, ConfigEvent = EventType,
          ActorEmail, ConfigIp = tostring(ActorSession.ip_address);
  let abuseSignals =
      OpenAIChatCompletions
      | where TimeGenerated > ago(window)
      | where EventFinishReasons has_any ("content_filter", "length")
          or array_length(EventFinishReasons) == 0
      | extend ActorUser = tolower(tostring(AdditionalFields.input_user))
      | where isnotempty(ActorUser)
      | project
          AbuseTime = TimeGenerated, ActorUser, ModelName,
          EventFinishReasons, EventRequestId;
  configChanges
  | join kind=inner abuseSignals on $left.ActorEmail == $right.ActorUser
  | where AbuseTime between (ConfigTime .. ConfigTime + 24h)
  | project
      ConfigTime, ConfigEvent, ActorEmail, ConfigIp,
      AbuseTime, ModelName, EventFinishReasons, EventRequestId
  | order by ConfigTime desc
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: ActorEmail
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: ConfigIp
- entityType: CloudApplication
  fieldMappings:
  - identifier: Name
    columnName: ModelName
eventGroupingSettings:
  aggregationKind: SingleAlert
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: PT24H
    matchingMethod: Selected
    groupByEntities:
    - Account
    groupByAlertDetails: []
    groupByCustomDetails: []
version: 1.0.0
kind: Scheduled
tags:
- Sentinel-As-Code
- Custom
- OpenAI
- AI

Explanation

This query is designed to detect suspicious activity related to OpenAI configurations and usage. Here's a simplified explanation:

  1. Purpose: The query aims to identify cases where a privileged configuration change (like changes in organization settings, roles, or creation of keys and projects) is followed by potentially abusive actions by the same user within 24 hours.

  2. Data Sources: It uses data from OpenAI audit logs and chat completion logs to track configuration changes and subsequent model requests.

  3. Process:

    • It looks for configuration changes made by users, capturing details like the time of change, type of event, user email, and IP address.
    • It also monitors for model requests that trigger abuse signals, such as hitting a content filter, being truncated for length, or having no finish reason.
    • The query then matches these configuration changes with abuse signals based on the user's email.
  4. Timeframe: The query checks for these activities within a 24-hour window.

  5. Alert Generation: If such a pattern is detected, an alert is generated with high severity, indicating potential persistence, defense evasion, or execution tactics.

  6. Incident Management: The query is set to create incidents in the system, grouping alerts by user account for better incident management.

  7. Customization: The query can be adjusted to fit specific tenant configurations, especially regarding how user identities are mapped.

Overall, this query helps in identifying and responding to potential security threats by correlating configuration changes with suspicious usage patterns.

Details

David Alonso profile picture

David Alonso

Released: June 8, 2026

Tables

OpenAIAuditLogsOpenAIChatCompletions

Keywords

OpenAIDevicesUserAccountIPCloudApplication

Operators

letwherehas_anytolowertostringisnotemptyprojectjoinonbetweenorder bydescagoextendarray_length

Actions