LoFP LoFP / documentation and unit tests that paste example keys, such as an aws access key ending in example, match the token patterns. confirm the value is live before rotating it.

Techniques

Sample rules

Microsoft Foundry Prompt or Completion Containing Credentials

Description

Detects a Microsoft Foundry chat, sent through API Management, whose prompt or assistant reply contains a known credential pattern or an email address together with a password assignment. The model often refuses the request and Azure content filters stay clear, so the secret is only visible in the logged message text.

Detection logic

from logs-azure_ai_foundry.logs-* metadata _id, _version, _index
| eval
    Esql.prompt_text = mv_concat(azure.ai_foundry.properties.backend_request_body.messages.content, " "),
    Esql.reply_text = mv_concat(azure.ai_foundry.properties.backend_response_body.choices.message.content, " ")
| where
    data_stream.dataset == "azure_ai_foundry.logs" and
    azure.ai_foundry.category == "GatewayLogs" and
    (
        Esql.prompt_text rlike """.*(AKIA|ASIA)[A-Z0-9]{16}.*""" or
        Esql.reply_text rlike """.*(AKIA|ASIA)[A-Z0-9]{16}.*""" or
        Esql.prompt_text rlike """.*gh[pousr]_[A-Za-z0-9]{36}.*""" or
        Esql.reply_text rlike """.*gh[pousr]_[A-Za-z0-9]{36}.*""" or
        Esql.prompt_text rlike """.*github_pat_[A-Za-z0-9_]+.*""" or
        Esql.reply_text rlike """.*github_pat_[A-Za-z0-9_]+.*""" or
        Esql.prompt_text rlike """.*-----BEGIN [A-Z ]*PRIVATE KEY-----.*""" or
        Esql.reply_text rlike """.*-----BEGIN [A-Z ]*PRIVATE KEY-----.*""" or
        Esql.prompt_text rlike """.*xox[baprs]-[0-9]+-[0-9]+-[A-Za-z0-9]+.*""" or
        Esql.reply_text rlike """.*xox[baprs]-[0-9]+-[0-9]+-[A-Za-z0-9]+.*""" or
        Esql.prompt_text rlike """.*sk_live_[A-Za-z0-9]+.*""" or
        Esql.reply_text rlike """.*sk_live_[A-Za-z0-9]+.*""" or
        Esql.prompt_text rlike """.*AIza[-A-Za-z0-9_]+.*""" or
        Esql.reply_text rlike """.*AIza[-A-Za-z0-9_]+.*""" or
        Esql.prompt_text rlike """.*npm_[A-Za-z0-9]+.*""" or
        Esql.reply_text rlike """.*npm_[A-Za-z0-9]+.*""" or
        Esql.prompt_text rlike """.*SG[.][-A-Za-z0-9_]+[.][-A-Za-z0-9_]+.*""" or
        Esql.reply_text rlike """.*SG[.][-A-Za-z0-9_]+[.][-A-Za-z0-9_]+.*""" or
        Esql.prompt_text rlike """.*(AccountKey=|SharedAccessKey=)[-A-Za-z0-9+/=]+.*""" or
        Esql.reply_text rlike """.*(AccountKey=|SharedAccessKey=)[-A-Za-z0-9+/=]+.*""" or
        Esql.prompt_text rlike """.*eyJ[-A-Za-z0-9_]+[.]eyJ[-A-Za-z0-9_]+[.][-A-Za-z0-9_]+.*""" or
        Esql.reply_text rlike """.*eyJ[-A-Za-z0-9_]+[.]eyJ[-A-Za-z0-9_]+[.][-A-Za-z0-9_]+.*""" or
        (
            Esql.prompt_text rlike """.*[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+[.][A-Za-z]{2,}.*""" and
            Esql.prompt_text rlike """.*([Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|[Pp][Aa][Ss][Ss][Ww][Dd]|[Pp][Ww][Dd])\s*(is|=|:)\s*\S+.*"""
        ) or
        (
            Esql.reply_text rlike """.*[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+[.][A-Za-z]{2,}.*""" and
            Esql.reply_text rlike """.*([Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|[Pp][Aa][Ss][Ss][Ww][Dd]|[Pp][Ww][Dd])\s*(is|=|:)\s*\S+.*"""
        )
    )
| keep
    _id,
    _version,
    _index,
    @timestamp,
    source.ip,
    azure.ai_foundry.properties.user_agent,
    azure.ai_foundry.properties.apim_subscription_id,
    azure.ai_foundry.properties.api_id,
    azure.ai_foundry.properties.operation_id,
    azure.ai_foundry.properties.backend_response_body.model,
    azure.ai_foundry.service_name,
    azure.resource.group,
    url.domain,
    url.path,
    source.geo.country_iso_code,
    source.geo.city_name,
    source.as.organization.name,
    azure.ai_foundry.properties.backend_request_body.messages.content,
    azure.ai_foundry.properties.backend_response_body.choices.message.content