Detection rules › Panther

Panther rules: auth0

Auth0 Attack Protection Monitoring Disabled

#
Severity
high
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

An attack protection monitoring configuration was changed.

MITRE ATT&CK coverage

TacticTechniques
Defense Impairment

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_type = event.deep_get("data", "type", default="<NO_DATA_TYPE_FOUND>")

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")

    request_path = event.deep_get(
        "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
    )

    response_body_enabled = event.deep_get(
        "data", "details", "response", "body", "enabled", default="<NO_ENABLED_INFO_FOUND>"
    )

    response_body_shields = event.deep_get(
        "data", "details", "response", "body", "shields", default="<NO_SHIELD_INFO_FOUND>"
    )

    response_status_code = event.deep_get(
        "data", "details", "response", "statusCode", default="<NO_RESPONSE_CODE_FOUND>"
    )

    return all(
        [
            data_type == "sapi",
            (
                (
                    "Suspicious IP Throttling" in data_description
                    and request_path == "/v2/attack-protection/suspicious-ip-throttling"
                )
                or (
                    "Brute-force" in data_description
                    and request_path == "/v2/attack-protection/brute-force-protection"
                )
                or (
                    "Breached Password Detection" in data_description
                    and request_path == "/v2/attack-protection/breached-password-detection"
                )
            ),
            (
                (response_body_enabled is False or response_body_enabled == "disabled")
                or (
                    (response_body_enabled is True or response_body_enabled == "enabled")
                    and response_body_shields != "block"
                )
            ),
            response_status_code == 200,
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")

    response_body_enabled = event.deep_get(
        "data", "details", "response", "body", "enabled", default="<NO_ENABLED_INFO_FOUND>"
    )

    response_body_shields = event.deep_get(
        "data", "details", "response", "body", "shields", default="<NO_SHIELD_INFO_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] updated shields to [{response_body_shields}]"
        f"or set attack protection monitoring to [{response_body_enabled}]"
        f"with message [{data_description}] in"
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An attack protection monitoring configuration was changed.
DisplayName: "Auth0 Attack Protection Monitoring Disabled"
Enabled: true
Filename: auth0_attack_protection_disabled.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://github.com/auth0/auth0-customer-detections/tree/main/detections
Severity: High
Reports:
  MITRE ATT&CK:
    - TA0005:T1562
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.AttackProtection.Disabled"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.type is sapi
  • any of:
    • all of:
      • data.description contains Suspicious IP Throttling
      • data.details.request.path is /v2/attack-protection/suspicious-ip-throttling
    • all of:
      • data.description contains Brute-force
      • data.details.request.path is /v2/attack-protection/brute-force-protection
    • all of:
      • data.description contains Breached Password Detection
      • data.details.request.path is /v2/attack-protection/breached-password-detection
  • any of:
    • data.details.response.body.enabled is false
    • data.details.response.body.enabled is disabled
    • all of:
      • any of:
        • data.details.response.body.enabled is true
        • data.details.response.body.enabled is enabled
      • data.details.response.body.shields is not block
  • data.details.response.statusCode is 200
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
shieldsdata.details.response.body.shields
enableddata.details.response.body.enabled
descriptiondata.description
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-03 14:09:32.149000000",
    "description": "Update Suspicious IP Throttling settings",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000ecaf1bfbadb06900d22049"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "enabled": true
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/v2/attack-protection/suspicious-ip-throttling",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": {
          "enabled": false
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-23 20:47:51.149",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-23 20:49:28.671",
  "p_row_id": "00000000004a745ce33b57be383c543e",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 Bot Detection Policy Disabled

#
Severity
high
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

A bot detection policy was disabled.

MITRE ATT&CK coverage

TacticTechniques
Defense Impairment

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_type = event.deep_get("data", "type", default="<NO_DATA_TYPE_FOUND>")

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")

    bot_p_policy = event.deep_get(
        "data",
        "details",
        "response",
        "body",
        "passwordless_policy",
        default="<NO_PASSWORDLESS_POLICY_FOUND>",
    )

    bot_reset_policy = event.deep_get(
        "data",
        "details",
        "response",
        "body",
        "password_reset_policy",
        default="<NO_PASSWORD_RESET_POLICY_FOUND>",
    )

    bot_policy = event.deep_get(
        "data", "details", "response", "body", "policy", default="<NO_BOT_POLICY_FOUND>"
    )

    response_status_code = event.deep_get(
        "data", "details", "response", "statusCode", default="<NO_RESPONSE_CODE_FOUND>"
    )
    return all(
        [
            data_type == "sapi",
            (
                data_description == "Create or update the anomaly detection captcha"
                and (bot_p_policy == "off" or bot_reset_policy == "off" or bot_policy == "off")
            ),
            response_status_code == 200,
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] disabled bot detection in "
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: A bot detection policy was disabled.
DisplayName: "Auth0 Bot Detection Policy Disabled"
Enabled: true
Filename: auth0_bot_detection_disabled.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://github.com/auth0/auth0-customer-detections/tree/main/detections
Severity: High
Reports:
  MITRE ATT&CK:
    - TA0005:T1562
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.BotDetection.Disabled"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.type is sapi
  • data.description is Create or update the anomaly detection captcha
  • any of:
    • data.details.response.body.passwordless_policy is off
    • data.details.response.body.password_reset_policy is off
    • data.details.response.body.policy is off
  • data.details.response.statusCode is 200
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-03 14:09:32.149000000",
    "description": "Create or update the anomaly detection captcha",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000ecaf1bfbadb06900d22049"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "enabled": true
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/v2/attack-protection/bot-detection",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": {
          "password_reset_policy": false,
          "passwordless_policy": false,
          "policy": false
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-23 20:47:51.149",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-23 20:49:28.671",
  "p_row_id": "00000000004a745ce33b57be383c543e",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 Brute Force

#
Severity
medium
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

Scheduled rule for brute force detection for Auth0 login or signup which looks for incidents of more than 10 incidents in one hour

Detection logic

from panther_core import PantherEvent


def rule(event: PantherEvent) -> bool:  # pylint: disable=unused-argument
    return True


def title(event: PantherEvent) -> str:
    total_incidents = event.get("total_incidents", 5)
    return f"Auth0 Brute Force detected: {total_incidents} attempts in the past hour"

Rule specification

AnalysisType: scheduled_rule
Filename: auth0_login_brute_force.py
DisplayName: "Auth0 Brute Force"
Enabled: true
Severity: Medium
Description: Scheduled rule for brute force detection for Auth0 login or signup which looks for incidents of more than 10 incidents in one hour
DedupPeriodMinutes: 60
Threshold: 1
Reference: https://auth0.com/docs/deploy-monitor/logs/log-event-type-codes
InlineFilters:
    - All: []
ScheduledQueries:
    - Auth0 Brute Force Detection
RuleID: "Auth0.Brute.Force"

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Auth0 Brute Force Detection; its Python module (Detection logic above) shapes the alert rather than filtering.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
total_incidents

Auth0 Brute Force Detection

#

Rule specification

AnalysisType: scheduled_query
QueryName: Auth0 Brute Force Detection
Enabled: false
# run every hour and look for >= 5 incidents in the last hour
SnowflakeQuery: |
  SELECT
   data, COUNT(*) OVER () AS total_incidents
  FROM
   panther_logs.public.auth0_events
  WHERE
   data:type IN ('limit_mu', 'limit_sul', 'limit_wc')
   AND p_occurs_since('1 hour')
  QUALIFY COUNT(*) OVER () > 4

DatabricksQuery: |
  SELECT * FROM (
    SELECT
      data, COUNT(*) OVER () AS total_incidents
    FROM
      panther_logs.auth0_events
    WHERE
      data:type IN ('limit_mu', 'limit_sul', 'limit_wc')
      AND p_occurs_since('1 hour')
  ) WHERE total_incidents > 4

Schedule:
  CronExpression: '0 * * * *'
  TimeoutMinutes: 1

Stages and Predicates

Stage 1: source

Table
panther_logs.public.auth0_events

Stage 2: filter

  • data:type is one of limit_mu, limit_sul, limit_wc
Window
1h

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data:typein
  • limit_mu
  • limit_sul
  • limit_wc
field:"data:type" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
data
total_incidentsCOUNT ( * ) OVER ( )

Auth0 CIC Credential Stuffing

#
Severity
high
Log types
Auth0.Events
Reference
sec.okta.com
Source
github.com/panther-labs/panther-analysis

Okta has determined that the cross-origin authentication feature in Customer Identity Cloud (CIC) is prone to being targeted by threat actors orchestrating credential-stuffing attacks. Okta has observed suspicious activity that started on April 15, 2024. Review tenant logs for unexpected fcoa and scoa events.

Detection logic

from panther_auth0_helpers import auth0_alert_context

SUSPICIOUS_EVENT_TYPES = (
    "scoa",
    "fcoa",
)


def rule(event):
    return event.deep_get("data", "type") in SUSPICIOUS_EVENT_TYPES


def title(event):
    event_type = event.deep_get("data", "type")
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] had a suspicious [{event_type}] event in "
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
LogTypes:
  - Auth0.Events
RuleID: "Auth0.CIC.Credential.Stuffing"
Filename: auth0_cic_credential_stuffing.py
DisplayName: "Auth0 CIC Credential Stuffing"
Description: Okta has determined that the cross-origin authentication feature in Customer Identity Cloud (CIC) is prone to being targeted by threat actors orchestrating credential-stuffing attacks.  Okta has observed suspicious activity that started on April 15, 2024.  Review tenant logs for unexpected fcoa and scoa events.
Enabled: true
Severity: High
Runbook: If a user password was compromised in a credential stuffing attack, the user's credentials should be rotated immediately out of an abundance of caution.
Reference: https://sec.okta.com/articles/2024/05/detecting-cross-origin-authentication-credential-stuffing-attacks
DedupPeriodMinutes: 60
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when the condition below holds.

Condition

  • data.type is one of scoa, fcoa

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data.typein
  • fcoa
  • scoa
field:"data.type" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
typedata.type
p_source_label

Response runbook

If a user password was compromised in a credential stuffing attack, the user's credentials should be rotated immediately out of an abundance of caution.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "audience": "https://shared.app-api.clientdomain.com",
    "client_id": "EmEDkk1wKV0bmzZut3rbEC5vxBE6UiZV",
    "client_name": "App Frontend",
    "connection": "Username-Password-Authentication",
    "connection_id": "con_BvGURiLLdngYaT0D",
    "date": "2024-10-29 18:52:51.953000000",
    "description": "Unable to configure verification page.",
    "details": {
      "body": {},
      "connection": "Username-Password-Authentication",
      "error": {
        "message": "Unable to configure verification page.",
        "oauthError": "server_error",
        "type": "oauth-authorization"
      },
      "qs": {
        "_csrf": "TUReBWZ8-Fp9mvFrk6S3beuGrvKIkZVFfcKk",
        "_intstate": "deprecated",
        "audience": "https://shared.app-api.clientdomain.com",
        "auth0Client": "eyJuYW1lIjoibG9jay5qcyIsInZlcnNpb24iOiIxMi4nYjOnsiYXV0aDAuanMiOiI5LjI2LjAifX0=",
        "client_id": "EmEDkk1wKV0bmzZut3rbE0C5vxBE6UiZV",
        "code_challenge": "oDe_o-4xT4_qdBvbbDiHPlVyoNKglqtNKqYrzcZt72M",
        "code_challenge_method": "S256",
        "connection": "Username-Password-Authentication",
        "login_hint": "",
        "login_ticket": "Uyqi3p1wDRZIWomeW3XxbjmSiBYNHzT8",
        "nonce": "eW9wRjRhTFpMNlYyNHNJT1NvRm1jUUl0sM2ZxYk80azZILjdSVnBMcy14cg==",
        "protocol": "oauth2",
        "realm": "Username-Password-Authentication",
        "redirect_uri": "https://redirect.app.clientdomain.com",
        "response_mode": "query",
        "response_type": "code",
        "scope": "openid profile email offline_access",
        "screen_hint": "login",
        "state": "hKFo2SBPSW1RRnlhcjhxUVJZLUVwNzI0SzVjM3ItT10E4NXdMdKFupWxvZ2luo3RpZNkgdWtpQXVpakxnRlZ5Tm1ER2k4a0szTXZXLXNFSzQ5cFajY2lk2SBFbUVEa2sxd0tWMGJtelp1dDNyYkVDNXZ4QkU2VWlaVg"
      },
      "session_id": "OJ0d2L-gDTvkmwEctP8d3XwtLD8Yu1qh"
    },
    "hostname": "auth.clientdomain.com",
    "ip": "2605:59c8:3075:214:d003:e902:2b01:dc14",
    "log_id": "90020241029185251974499000000000000001223372087732751235",
    "scope": [
      "openid",
      "profile",
      "email",
      "offline_access"
    ],
    "type": "fcoa",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
  },
  "log_id": "90020241029185251974499000000000000001223372087732751235"
}

Auth0 CIC Credential Stuffing Query

#
Source
github.com/panther-labs/panther-analysis

Okta has determined that the cross-origin authentication feature in Customer Identity Cloud (CIC) is prone to being targeted by threat actors orchestrating credential-stuffing attacks. Okta has observed suspicious activity that started on April 15, 2024. Review tenant logs for unexpected fcoa, scoa, and pwd_leak events. https://sec.okta.com/articles/2024/05/detecting-cross-origin-authentication-credential-stuffing-attacks

Rule specification

AnalysisType: saved_query
QueryName: "Auth0 CIC Credential Stuffing Query"
Description: Okta has determined that the cross-origin authentication feature in Customer Identity Cloud (CIC) is prone to being targeted by threat actors orchestrating credential-stuffing attacks.  Okta has observed suspicious activity that started on April 15, 2024.  Review tenant logs for unexpected fcoa, scoa, and pwd_leak events.  https://sec.okta.com/articles/2024/05/detecting-cross-origin-authentication-credential-stuffing-attacks
SnowflakeQuery: |-
  SELECT
   *
  FROM
       panther_logs.public.auth0_events
  WHERE
       data:type in ('fcoa', 'scoa', 'pwd_leak')
       and p_occurs_between('2024-04-14', current_timestamp)

DatabricksQuery: |-
  SELECT
   *
  FROM
       panther_logs.auth0_events
  WHERE
       data:type in ('fcoa', 'scoa', 'pwd_leak')
       and p_occurs_between('2024-04-14', current_timestamp)

Stages and Predicates

Stage 1: source

Table
panther_logs.public.auth0_events

Stage 2: filter

  • data:type is one of fcoa, scoa, pwd_leak

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data:typein
  • fcoa
  • pwd_leak
  • scoa
field:"data:type" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

Field
*

Auth0 Custom Role Created

#
Severity
high
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 User created a role in your organization's tenant.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    return all(
        [
            data_description == "Create a role",
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    request_body_name = event.deep_get(
        "data", "details", "request", "body", "name", default="<NO_REQUEST_NAME_FOUND>"
    )
    request_body_description = event.deep_get(
        "data", "details", "request", "body", default="<NO_REQUEST_BODY_FOUND>"
    )

    if "admin" in request_body_description or "admin" in request_body_name:
        role_type = "admin"
    else:
        role_type = "custom"

    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] created a "
        f"role [{request_body_name}] with [{role_type}] "
        f"permissions in your tenant [{p_source_label}]."
    )


def severity(event):
    request_body_name = event.deep_get(
        "data", "details", "request", "body", "name", default="<NO_REQUEST_NAME_FOUND>"
    )
    request_body_description = event.deep_get(
        "data", "details", "request", "body", "description", default=""
    )
    if "admin" in request_body_description or "admin" in request_body_name:
        return "MEDIUM"
    return "LOW"


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 User created a role in your organization's tenant.
DisplayName: "Auth0 Custom Role Created"
Enabled: true
Filename: auth0_custom_role_created.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant if a user created a role without proper authorization.
Reference: https://auth0.com/docs/manage-users/access-control/configure-core-rbac/roles/create-roles
Severity: High
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.Custom.Role.Created"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Create a role
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
namedata.details.request.body.name
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant if a user created a role without proper authorization.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-16 17:28:11.165000000",
    "description": "Create a role",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0107c849078d8d889af711840197ba7c",
            "scopes": [
              "create:actions",
              "create:actions_log_sessions",
              "create:authentication_methods",
              "create:client_credentials",
              "create:client_grants",
              "create:clients",
              "create:connections",
              "create:custom_domains",
              "create:email_provider",
              "create:email_templates",
              "create:guardian_enrollment_tickets",
              "create:integrations",
              "create:log_streams",
              "create:organization_connections",
              "create:organization_invitations",
              "create:organization_member_roles",
              "create:organization_members",
              "create:organizations",
              "create:requested_scopes",
              "create:resource_servers",
              "create:roles",
              "create:rules",
              "create:shields",
              "create:signing_keys",
              "create:tenant_invitations",
              "create:test_email_dispatch",
              "create:users",
              "delete:actions",
              "delete:anomaly_blocks",
              "delete:authentication_methods",
              "delete:branding",
              "delete:client_credentials",
              "delete:client_grants",
              "delete:clients",
              "delete:connections",
              "delete:custom_domains",
              "delete:device_credentials",
              "delete:email_provider",
              "delete:email_templates",
              "delete:grants",
              "delete:guardian_enrollments",
              "delete:integrations",
              "delete:log_streams",
              "delete:organization_connections",
              "delete:organization_invitations",
              "delete:organization_member_roles",
              "delete:organization_members",
              "delete:organizations",
              "delete:owners",
              "delete:requested_scopes",
              "delete:resource_servers",
              "delete:roles",
              "delete:rules",
              "delete:rules_configs",
              "delete:shields",
              "delete:tenant_invitations",
              "delete:tenant_members",
              "delete:tenants",
              "delete:users",
              "read:actions",
              "read:anomaly_blocks",
              "read:attack_protection",
              "read:authentication_methods",
              "read:branding",
              "read:checks",
              "read:client_credentials",
              "read:client_grants",
              "read:client_keys",
              "read:clients",
              "read:connections",
              "read:custom_domains",
              "read:device_credentials",
              "read:email_provider",
              "read:email_templates",
              "read:email_triggers",
              "read:entity_counts",
              "read:grants",
              "read:guardian_factors",
              "read:insights",
              "read:integrations",
              "read:log_streams",
              "read:logs",
              "read:mfa_policies",
              "read:organization_connections",
              "read:organization_invitations",
              "read:organization_member_roles",
              "read:organization_members",
              "read:organizations",
              "read:prompts",
              "read:requested_scopes",
              "read:resource_servers",
              "read:roles",
              "read:rules",
              "read:rules_configs",
              "read:shields",
              "read:signing_keys",
              "read:stats",
              "read:tenant_invitations",
              "read:tenant_members",
              "read:tenant_settings",
              "read:triggers",
              "read:users",
              "run:checks",
              "update:actions",
              "update:attack_protection",
              "update:authentication_methods",
              "update:branding",
              "update:client_credentials",
              "update:client_grants",
              "update:client_keys",
              "update:clients",
              "update:connections",
              "update:custom_domains",
              "update:email_provider",
              "update:email_templates",
              "update:email_triggers",
              "update:guardian_factors",
              "update:integrations",
              "update:log_streams",
              "update:mfa_policies",
              "update:organization_connections",
              "update:organizations",
              "update:prompts",
              "update:requested_scopes",
              "update:resource_servers",
              "update:roles",
              "update:rules",
              "update:rules_configs",
              "update:shields",
              "update:signing_keys",
              "update:tenant_members",
              "update:tenant_settings",
              "update:triggers",
              "update:users"
            ]
          },
          "strategy": "jwt",
          "user": {
            "email": "user.name@yourcompany.io",
            "name": "User Name",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "description": "test",
          "name": "test"
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "put",
        "path": "/api/v2/guardian/policies",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": [],
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230516172812328948000000000000001223372037498448373",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230516172812328948000000000000001223372037498448373",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-16 17:28:11.165",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-16 17:29:28.904",
  "p_row_id": "a2d1b1713461e7a5f1b08f991886e402",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Tenant Label"
}

Auth0 Delete Tenant Member

#
Severity
informational
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

A tenant member was deleted.

MITRE ATT&CK coverage

TacticTechniques
Exfiltration

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")

    return all(
        [
            is_auth0_config_event(event),
            data_description == "Delete tenant member",
        ]
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Filename: auth0_delete_tenant_member.py
RuleID: Auth0.Delete.TenantMember
DisplayName: Auth0 Delete Tenant Member
Enabled: true
LogTypes:
  - Auth0.Events
Severity: Info
CreateAlert: false
Reports:
  MITRE ATT&CK:
    - TA0010:T1041
Description: A tenant member was deleted.
Reference: 
  https://github.com/auth0/auth0-customer-detections/blob/main/detections/risk_of_tenant_takeover.yml

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.details.request.channel is https://manage.auth0.com/
  • data.description is Delete tenant member

Indicators

These rows show field, operator, and value matches.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-10 10:27:51.149000000",
    "description": "Delete tenant member",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000311abf72f7a0ce7a303592"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77",
          "roles": [
            "owner",
            "user"
          ]
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/api/v2/integrations/installed",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "signup_pwd_leak",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452"
}

Auth0 Fraud Risk by Volume

#
Severity
high
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

Detects a surge in either failed, successful or suspicious login attempts using leaked passwords over a window of time and a threshold. Exceeding set threshold may indicate potential fraud.

MITRE ATT&CK coverage

TacticTechniques
Persistence

Detection logic

from panther_auth0_helpers import auth0_alert_context

SUSPICIOUS_EVENT_TYPES = (
    "fs",
    "ss",
    "signup_pwd_leak",
)


def rule(event):
    return event.deep_get("data", "type") in SUSPICIOUS_EVENT_TYPES


def title(event):
    event_type = event.deep_get("data", "type")
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] had a surge of suspicious [{event_type}] event in "
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
RuleID: "Auth0.FraudRisk.Volume"
Filename: auth0_fraud_risk_volume.py
LogTypes:
  - Auth0.Events
DisplayName: "Auth0 Fraud Risk by Volume"
Description: Detects a surge in either failed, successful or suspicious login attempts using leaked passwords over a window of time and a threshold. Exceeding set threshold may indicate potential fraud.
Enabled: true
Severity: High
Reports:
  MITRE ATT&CK:
    - TA0003:T1136
Reference: https://github.com/auth0/auth0-customer-detections/blob/main/detections/risk_of_signup_fraud_by_volume.yml
DedupPeriodMinutes: 60
Threshold: 20

Stages and Predicates

Fires on Auth0.Events events when the condition below holds.

Condition

  • data.type is one of fs, ss, signup_pwd_leak
Alert cadence
alerts after 20 matches within 1h

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data.typein
  • fs
  • signup_pwd_leak
  • ss
field:"data.type" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
typedata.type
p_source_label

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-10 10:27:51.149000000",
    "description": "Someone behind the IP address ip attempted to login with a leaked password.",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000311abf72f7a0ce7a303592"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/api/v2/integrations/installed",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "signup_pwd_leak",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452"
}

Auth0 Integration Installed

#
Severity
informational
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 integration was installed from the auth0 action library.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    request_path = event.deep_get(
        "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
    )
    return all(
        [
            data_description == "Install an available integration",
            request_path == "/api/v2/integrations/installed",
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] installed an integration from the actions library for "
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 integration was installed from the auth0 action library.
DisplayName: "Auth0 Integration Installed"
Enabled: true
Filename: auth0_integration_installed.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://auth0.com/blog/actions-integrations-are-now-ga/
Severity: Info
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.Integration.Installed"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Install an available integration
  • data.details.request.path is /api/v2/integrations/installed
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-23 20:47:51.149000000",
    "description": "Install an available integration",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "e6343ec1d24a41e6bd43a6be748cac11"
          },
          "strategy": "jwt",
          "user": {
            "email": "homer.simpson@yourcompany.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/api/v2/integrations/installed",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-23 20:47:51.149",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-23 20:49:28.671",
  "p_row_id": "826b85e235b6f5cbd8fd85ab18dfb703",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 Leaked Password Login Attempt

#
Severity
medium
Log types
Auth0.Events
Source
github.com/panther-labs/panther-analysis

Detect Auth0 Leaked Password Login Attempt

Detection logic

from panther_core import PantherEvent


def rule(event: PantherEvent) -> bool:
    return event.deep_get("data", "type") == "pwd_leak"


def title(event: PantherEvent) -> str:
    ip_address = event.deep_get("data", "ip", default="NO_IP_FOUND")
    user_name = event.deep_get("data", "user_name", default="NO_USERNAME")
    event_title = (
        "Someone behind the IP address {} attempted to login with a leaked password "
        "with username {}"
    )

    return event_title.format(ip_address, user_name)

Rule specification

AnalysisType: rule
Description: Detect Auth0 Leaked Password Login Attempt
DisplayName: "Auth0 Leaked Password Login Attempt"
Enabled: true
Filename: auth0_leaked_password_login_attempt.py
Severity: Medium
DedupPeriodMinutes: 60
Threshold: 1
LogTypes:
  - Auth0.Events
RuleID: "Auth0.Leaked.Password.Login.Attempt"

Stages and Predicates

Fires on Auth0.Events events when the condition below holds.

Condition

  • data.type is pwd_leak

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
ipdata.ip
user_namedata.user_name

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "11Qpq1o8fbGgnZuFJnQCyjuC1ll8YFt0",
    "connection": "Username-Password-Authentication",
    "connection_id": "con_BvGURiLLdngYaT0D",
    "date": "2025-10-01 05:39:16.467000000",
    "description": "Someone behind the IP address: 2601:140:9702:ee80:0000:1f55:93a7:e970 attempted to login with a leaked password. A shield to prevent this action was enabled, further attempts are blocked.",
    "hostname": "auth.clientdomain.com",
    "ip": "2601:140:9702:ee80:9049:1f55:0000:e970",
    "log_id": "90020251001053916537654000000000000001223372122475524001",
    "type": "pwd_leak",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
    "user_id": "",
    "user_name": "denethor@lotr.com"
  },
  "log_id": "90020251001053916537654000000000000001223372122475524001"
}

Auth0 Limit Detections

#
Severity
medium
Log types
Auth0.Events
Source
github.com/panther-labs/panther-analysis

Detect Auth0 Limit Logs

Detection logic

from panther_core import PantherEvent

SUSPICIOUS_EVENT_TYPES = (
    "api_limit",
    "gd_otp_rate_limit_exceed",
    "gd_recovery_rate_limit_exceed",
    "limit_delegation",
    "limit_mu",
    "limit_sul",
    "limit_wc",
)

EVENT_TITLES = (
    "The maximum number of requests to the Authentication or Management APIs has been "
    "reached for {}",
    "Too many MFA failures occured for {}",
    "{} has entered a wrong recovery code too many times",
    "Rate limit exceeded to the delegation token endpoint by {}",
    "{} IP address is blocked because it attempted too many sign-ups or failed logins: {}",
    "{} is temporarily blocked from logging in because they reached the maximum logins from {}",
    "{} IP address is blocked because it reached the maximum failed login attempts into a "
    "single account: {}",
)


def rule(event: PantherEvent) -> bool:
    return event.deep_get("data", "type") in SUSPICIOUS_EVENT_TYPES


def title(event: PantherEvent) -> str:
    limit_mu_index = SUSPICIOUS_EVENT_TYPES.index("limit_mu")
    limit_sul_index = SUSPICIOUS_EVENT_TYPES.index("limit_sul")
    limit_wc_index = SUSPICIOUS_EVENT_TYPES.index("limit_wc")

    event_type = event.deep_get("data", "type")
    event_index = SUSPICIOUS_EVENT_TYPES.index(event_type)
    event_title = EVENT_TITLES[event_index]

    # limit_mu or limit_wc
    if event_index in {limit_mu_index, limit_wc_index}:
        ip_address = event.deep_get("data", "ip", default="NO_IP_FOUND")
        username = event.deep_get("data", "user_name", default="NO_USER_FOUND")
        return event_title.format(ip_address, username)

    # limit_sul
    if event_index == limit_sul_index:
        ip_address = event.deep_get("data", "ip", default="NO_IP_FOUND")
        username = event.deep_get("data", "user_name", default="NO_USER_FOUND")
        return event_title.format(username, ip_address)

    # other cases have only "user_name" field in their titles
    username = event.deep_get("data", "user_name", default="NO_USER_FOUND")
    return event_title.format(username)

Rule specification

AnalysisType: rule
Description: Detect Auth0 Limit Logs
DisplayName: "Auth0 Limit Detections"
Enabled: true
Filename: auth0_limits.py
Severity: Medium
DedupPeriodMinutes: 60
Threshold: 1
LogTypes:
  - Auth0.Events
RuleID: "Auth0.Limits"

Stages and Predicates

Fires on Auth0.Events events when the condition below holds.

Condition

  • data.type is one of api_limit, gd_otp_rate_limit_exceed, gd_recovery_rate_limit_exceed, limit_delegation, limit_mu (+2 more values, see Indicators below)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data.typein
  • api_limit
  • gd_otp_rate_limit_exceed
  • gd_recovery_rate_limit_exceed
  • limit_delegation
  • limit_mu
  • limit_sul
  • limit_wc
field:"data.type" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
ipdata.ip
user_namedata.user_name

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "11Qpq1o8fbGgnZuFJnQCyjuC1ll8YFt0",
    "connection": "Username-Password-Authentication",
    "connection_id": "con_BvGURiLLdngYaT0D",
    "date": "2025-09-30 21:23:49.689000000",
    "description": "User (john@justice.org) attempted 10 consecutive logins unsuccessfully. Brute force protection is enabled for this connection, further attempts are blocked from this IP address for this user.",
    "hostname": "auth.clientdomain.com",
    "ip": "1.2.3.4",
    "log_id": "90020250930212349746493000000000000001223372122436618809",
    "type": "limit_wc",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
    "user_id": "",
    "user_name": "john@justice.org"
  },
  "log_id": "90020250930212349746493000000000000001223372122436618809"
}

Auth0 mfa factor enabled

#
Severity
informational
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 user enabled an mfa factor in your organization's mfa settings.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    description = event.deep_get("data", "description", default="<NO_DESCRIPTION_FOUND>")
    enabled = event.deep_get("data", "details", "response", "body", "enabled")
    return all(
        [
            description == "Update a Multi-factor Authentication Factor",
            enabled is True,
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    path = event.deep_get("data", "details", "request", "path", default="<NO_PATH_FOUND>")
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] enabled mfa factor settings for [{path}] "
        f"in your organization’s tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 user enabled an mfa factor in your organization's mfa settings.
DisplayName: "Auth0 mfa factor enabled"
Enabled: true
Filename: auth0_mfa_factor_setting_enabled.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://auth0.com/docs/secure/multi-factor-authentication/multi-factor-authentication-factors
Severity: Info
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.MFA.Factor.Setting.Enabled"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Update a Multi-factor Authentication Factor
  • data.details.response.body.enabled is true
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
pathdata.details.request.path
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-15 21:55:18.060000000",
    "description": "Update a Multi-factor Authentication Factor",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "949869e066205b5076e6df203fdd7b9b",
            "scopes": [
              "create:actions",
              "create:actions_log_sessions",
              "create:authentication_methods",
              "create:client_credentials",
              "create:client_grants",
              "create:clients",
              "create:connections",
              "create:custom_domains",
              "create:email_provider",
              "create:email_templates",
              "create:guardian_enrollment_tickets",
              "create:integrations",
              "create:log_streams",
              "create:organization_connections",
              "create:organization_invitations",
              "create:organization_member_roles",
              "create:organization_members",
              "create:organizations",
              "create:requested_scopes",
              "create:resource_servers",
              "create:roles",
              "create:rules",
              "create:shields",
              "create:signing_keys",
              "create:tenant_invitations",
              "create:test_email_dispatch",
              "create:users",
              "delete:actions",
              "delete:anomaly_blocks",
              "delete:authentication_methods",
              "delete:branding",
              "delete:client_credentials",
              "delete:client_grants",
              "delete:clients",
              "delete:connections",
              "delete:custom_domains",
              "delete:device_credentials",
              "delete:email_provider",
              "delete:email_templates",
              "delete:grants",
              "delete:guardian_enrollments",
              "delete:integrations",
              "delete:log_streams",
              "delete:organization_connections",
              "delete:organization_invitations",
              "delete:organization_member_roles",
              "delete:organization_members",
              "delete:organizations",
              "delete:owners",
              "delete:requested_scopes",
              "delete:resource_servers",
              "delete:roles",
              "delete:rules",
              "delete:rules_configs",
              "delete:shields",
              "delete:tenant_invitations",
              "delete:tenant_members",
              "delete:tenants",
              "delete:users",
              "read:actions",
              "read:anomaly_blocks",
              "read:attack_protection",
              "read:authentication_methods",
              "read:branding",
              "read:checks",
              "read:client_credentials",
              "read:client_grants",
              "read:client_keys",
              "read:clients",
              "read:connections",
              "read:custom_domains",
              "read:device_credentials",
              "read:email_provider",
              "read:email_templates",
              "read:email_triggers",
              "read:entity_counts",
              "read:grants",
              "read:guardian_factors",
              "read:insights",
              "read:integrations",
              "read:log_streams",
              "read:logs",
              "read:mfa_policies",
              "read:organization_connections",
              "read:organization_invitations",
              "read:organization_member_roles",
              "read:organization_members",
              "read:organizations",
              "read:prompts",
              "read:requested_scopes",
              "read:resource_servers",
              "read:roles",
              "read:rules",
              "read:rules_configs",
              "read:shields",
              "read:signing_keys",
              "read:stats",
              "read:tenant_invitations",
              "read:tenant_members",
              "read:tenant_settings",
              "read:triggers",
              "read:users",
              "run:checks",
              "update:actions",
              "update:attack_protection",
              "update:authentication_methods",
              "update:branding",
              "update:client_credentials",
              "update:client_grants",
              "update:client_keys",
              "update:clients",
              "update:connections",
              "update:custom_domains",
              "update:email_provider",
              "update:email_templates",
              "update:email_triggers",
              "update:guardian_factors",
              "update:integrations",
              "update:log_streams",
              "update:mfa_policies",
              "update:organization_connections",
              "update:organizations",
              "update:prompts",
              "update:requested_scopes",
              "update:resource_servers",
              "update:roles",
              "update:rules",
              "update:rules_configs",
              "update:shields",
              "update:signing_keys",
              "update:tenant_members",
              "update:tenant_settings",
              "update:triggers",
              "update:users"
            ]
          },
          "strategy": "jwt",
          "user": {
            "email": "user.name@yourcompany.io",
            "name": "User Name",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "AfterAuthentication": false
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "patch",
        "path": "/api/v2/risk-assessment/config",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": {
          "Enabled": true
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230515215719063964000000000000001223372037488829643",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230515215719063964000000000000001223372037488829643",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-15 21:55:18.06",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-15 21:58:28.629",
  "p_row_id": "42b742dba9d5f3f284d49b971814",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Tenant Label"
}

Auth0 MFA Policy Disabled

#
Severity
high
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 User disabled MFA for your organization's tenant.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    request_path = event.deep_get(
        "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
    )
    request_body = event.deep_get("data", "details", "request", "body", default=[-1])
    return all(
        [
            data_description == "Set the Multi-factor Authentication policies",
            request_path == "/api/v2/guardian/policies",
            request_body == [],
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] set mfa requirement settings to 'Never' for your "
        f"organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 User disabled MFA for your organization's tenant.
DisplayName: "Auth0 MFA Policy Disabled"
Enabled: true
Filename: auth0_mfa_policy_disabled.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://auth0.com/docs/secure/multi-factor-authentication/enable-mfa#:~:text=prompted%20for%20MFA.-,Never,-%3A%20MFA%20is%20not
Severity: High
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.MFA.Policy.Disabled"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Set the Multi-factor Authentication policies
  • data.details.request.path is /api/v2/guardian/policies
  • data.details.request.body is []
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-16 17:28:11.165000000",
    "description": "Set the Multi-factor Authentication policies",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0107c849078d8d889af711840197ba7c",
            "scopes": [
              "create:actions",
              "create:actions_log_sessions",
              "create:authentication_methods",
              "create:client_credentials",
              "create:client_grants",
              "create:clients",
              "create:connections",
              "create:custom_domains",
              "create:email_provider",
              "create:email_templates",
              "create:guardian_enrollment_tickets",
              "create:integrations",
              "create:log_streams",
              "create:organization_connections",
              "create:organization_invitations",
              "create:organization_member_roles",
              "create:organization_members",
              "create:organizations",
              "create:requested_scopes",
              "create:resource_servers",
              "create:roles",
              "create:rules",
              "create:shields",
              "create:signing_keys",
              "create:tenant_invitations",
              "create:test_email_dispatch",
              "create:users",
              "delete:actions",
              "delete:anomaly_blocks",
              "delete:authentication_methods",
              "delete:branding",
              "delete:client_credentials",
              "delete:client_grants",
              "delete:clients",
              "delete:connections",
              "delete:custom_domains",
              "delete:device_credentials",
              "delete:email_provider",
              "delete:email_templates",
              "delete:grants",
              "delete:guardian_enrollments",
              "delete:integrations",
              "delete:log_streams",
              "delete:organization_connections",
              "delete:organization_invitations",
              "delete:organization_member_roles",
              "delete:organization_members",
              "delete:organizations",
              "delete:owners",
              "delete:requested_scopes",
              "delete:resource_servers",
              "delete:roles",
              "delete:rules",
              "delete:rules_configs",
              "delete:shields",
              "delete:tenant_invitations",
              "delete:tenant_members",
              "delete:tenants",
              "delete:users",
              "read:actions",
              "read:anomaly_blocks",
              "read:attack_protection",
              "read:authentication_methods",
              "read:branding",
              "read:checks",
              "read:client_credentials",
              "read:client_grants",
              "read:client_keys",
              "read:clients",
              "read:connections",
              "read:custom_domains",
              "read:device_credentials",
              "read:email_provider",
              "read:email_templates",
              "read:email_triggers",
              "read:entity_counts",
              "read:grants",
              "read:guardian_factors",
              "read:insights",
              "read:integrations",
              "read:log_streams",
              "read:logs",
              "read:mfa_policies",
              "read:organization_connections",
              "read:organization_invitations",
              "read:organization_member_roles",
              "read:organization_members",
              "read:organizations",
              "read:prompts",
              "read:requested_scopes",
              "read:resource_servers",
              "read:roles",
              "read:rules",
              "read:rules_configs",
              "read:shields",
              "read:signing_keys",
              "read:stats",
              "read:tenant_invitations",
              "read:tenant_members",
              "read:tenant_settings",
              "read:triggers",
              "read:users",
              "run:checks",
              "update:actions",
              "update:attack_protection",
              "update:authentication_methods",
              "update:branding",
              "update:client_credentials",
              "update:client_grants",
              "update:client_keys",
              "update:clients",
              "update:connections",
              "update:custom_domains",
              "update:email_provider",
              "update:email_templates",
              "update:email_triggers",
              "update:guardian_factors",
              "update:integrations",
              "update:log_streams",
              "update:mfa_policies",
              "update:organization_connections",
              "update:organizations",
              "update:prompts",
              "update:requested_scopes",
              "update:resource_servers",
              "update:roles",
              "update:rules",
              "update:rules_configs",
              "update:shields",
              "update:signing_keys",
              "update:tenant_members",
              "update:tenant_settings",
              "update:triggers",
              "update:users"
            ]
          },
          "strategy": "jwt",
          "user": {
            "email": "user.name@yourcompany.io",
            "name": "User Name",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": [],
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "put",
        "path": "/api/v2/guardian/policies",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": [],
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230516172812328948000000000000001223372037498448373",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230516172812328948000000000000001223372037498448373",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-16 17:28:11.165",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-16 17:29:28.904",
  "p_row_id": "a2d1b1713461e7a5f1b08f991886e402",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Tenant Label"
}

Auth0 MFA Policy Enabled

#
Severity
medium
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 User enabled MFA Policy for your organization's tenant.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    request_path = event.deep_get(
        "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
    )
    return all(
        [
            data_description == "Set the Multi-factor Authentication policies",
            request_path == "/api/v2/guardian/policies",
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user_email = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    request_body = event.deep_get("data", "details", "request", "body", default=[])

    if "all-applications" in request_body:
        setting_change = "Always Require"
    if "confidence-score" in request_body:
        setting_change = "Use Adaptive MFA"
    else:
        setting_change = "Unknown"

    return (
        f"Auth0 user [{user_email}] set the "
        f"mfa policies in your organization to [{setting_change}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 User enabled MFA Policy for your organization's tenant.
DisplayName: "Auth0 MFA Policy Enabled"
Enabled: true
Filename: auth0_mfa_policy_enabled.py
Runbook: Assess if this was done by the user for a valid business reason and was expected. This alert indicates a setting change that aligns with best security practices, follow-up may be unnecessary.
Reference: https://auth0.com/docs/secure/multi-factor-authentication/enable-mfa#:~:text=In%20the-,Define%20policies,-section%2C%20select%20a
Severity: Medium
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.MFA.Policy.Enabled"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Set the Multi-factor Authentication policies
  • data.details.request.path is /api/v2/guardian/policies
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email

Response runbook

Assess if this was done by the user for a valid business reason and was expected. This alert indicates a setting change that aligns with best security practices, follow-up may be unnecessary.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-16 17:26:16.782000000",
    "description": "Set the Multi-factor Authentication policies",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0107c849078d8d889af711840197ba7c",
            "scopes": [
              "create:actions",
              "create:actions_log_sessions",
              "create:authentication_methods",
              "create:client_credentials",
              "create:client_grants",
              "create:clients",
              "create:connections",
              "create:custom_domains",
              "create:email_provider",
              "create:email_templates",
              "create:guardian_enrollment_tickets",
              "create:integrations",
              "create:log_streams",
              "create:organization_connections",
              "create:organization_invitations",
              "create:organization_member_roles",
              "create:organization_members",
              "create:organizations",
              "create:requested_scopes",
              "create:resource_servers",
              "create:roles",
              "create:rules",
              "create:shields",
              "create:signing_keys",
              "create:tenant_invitations",
              "create:test_email_dispatch",
              "create:users",
              "delete:actions",
              "delete:anomaly_blocks",
              "delete:authentication_methods",
              "delete:branding",
              "delete:client_credentials",
              "delete:client_grants",
              "delete:clients",
              "delete:connections",
              "delete:custom_domains",
              "delete:device_credentials",
              "delete:email_provider",
              "delete:email_templates",
              "delete:grants",
              "delete:guardian_enrollments",
              "delete:integrations",
              "delete:log_streams",
              "delete:organization_connections",
              "delete:organization_invitations",
              "delete:organization_member_roles",
              "delete:organization_members",
              "delete:organizations",
              "delete:owners",
              "delete:requested_scopes",
              "delete:resource_servers",
              "delete:roles",
              "delete:rules",
              "delete:rules_configs",
              "delete:shields",
              "delete:tenant_invitations",
              "delete:tenant_members",
              "delete:tenants",
              "delete:users",
              "read:actions",
              "read:anomaly_blocks",
              "read:attack_protection",
              "read:authentication_methods",
              "read:branding",
              "read:checks",
              "read:client_credentials",
              "read:client_grants",
              "read:client_keys",
              "read:clients",
              "read:connections",
              "read:custom_domains",
              "read:device_credentials",
              "read:email_provider",
              "read:email_templates",
              "read:email_triggers",
              "read:entity_counts",
              "read:grants",
              "read:guardian_factors",
              "read:insights",
              "read:integrations",
              "read:log_streams",
              "read:logs",
              "read:mfa_policies",
              "read:organization_connections",
              "read:organization_invitations",
              "read:organization_member_roles",
              "read:organization_members",
              "read:organizations",
              "read:prompts",
              "read:requested_scopes",
              "read:resource_servers",
              "read:roles",
              "read:rules",
              "read:rules_configs",
              "read:shields",
              "read:signing_keys",
              "read:stats",
              "read:tenant_invitations",
              "read:tenant_members",
              "read:tenant_settings",
              "read:triggers",
              "read:users",
              "run:checks",
              "update:actions",
              "update:attack_protection",
              "update:authentication_methods",
              "update:branding",
              "update:client_credentials",
              "update:client_grants",
              "update:client_keys",
              "update:clients",
              "update:connections",
              "update:custom_domains",
              "update:email_provider",
              "update:email_templates",
              "update:email_triggers",
              "update:guardian_factors",
              "update:integrations",
              "update:log_streams",
              "update:mfa_policies",
              "update:organization_connections",
              "update:organizations",
              "update:prompts",
              "update:requested_scopes",
              "update:resource_servers",
              "update:roles",
              "update:rules",
              "update:rules_configs",
              "update:shields",
              "update:signing_keys",
              "update:tenant_members",
              "update:tenant_settings",
              "update:triggers",
              "update:users"
            ]
          },
          "strategy": "jwt",
          "user": {
            "email": "user.name@yourcompany.io",
            "name": "User Name",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": [
          "all-applications"
        ],
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "put",
        "path": "/api/v2/guardian/policies",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": [
          "all-applications"
        ],
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230515215719063964000000000000001223372037488829643",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230515215719063964000000000000001223372037488829643",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-16 17:26:16.782",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-16 17:28:28.572",
  "p_row_id": "2660c447622fa4c3dbb08f9918979102",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 MFA Risk Assessment Disabled

#
Severity
high
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 User disabled the mfa risk assessment setting for your organization's tenant.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    request_path = event.deep_get(
        "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
    )
    request_body = event.deep_get(
        "data", "details", "request", "body", "AfterAuthentication", default=[]
    )
    return all(
        [
            data_description == "Updates risk assessment configs",
            request_path == "/api/v2/risk-assessment/config",
            request_body is False,
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] disabled mfa risk assessment settings for your "
        f"organization’s tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 User disabled the mfa risk assessment setting for your organization's tenant.
DisplayName: "Auth0 MFA Risk Assessment Disabled"
Enabled: true
Filename: auth0_mfa_risk_assessment_disabled.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://auth0.com/docs/secure/multi-factor-authentication/enable-mfa#:~:text=Always%20policy%2C%20the-,MFA%20Risk%20Assessors,-section%20appears.%20By
Severity: High
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.MFA.Risk.Assessment.Disabled"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Updates risk assessment configs
  • data.details.request.path is /api/v2/risk-assessment/config
  • data.details.request.body.AfterAuthentication is false
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-15 21:55:18.060000000",
    "description": "Updates risk assessment configs",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "949869e066205b5076e6df203fdd7b9b",
            "scopes": [
              "create:actions",
              "create:actions_log_sessions",
              "create:authentication_methods",
              "create:client_credentials",
              "create:client_grants",
              "create:clients",
              "create:connections",
              "create:custom_domains",
              "create:email_provider",
              "create:email_templates",
              "create:guardian_enrollment_tickets",
              "create:integrations",
              "create:log_streams",
              "create:organization_connections",
              "create:organization_invitations",
              "create:organization_member_roles",
              "create:organization_members",
              "create:organizations",
              "create:requested_scopes",
              "create:resource_servers",
              "create:roles",
              "create:rules",
              "create:shields",
              "create:signing_keys",
              "create:tenant_invitations",
              "create:test_email_dispatch",
              "create:users",
              "delete:actions",
              "delete:anomaly_blocks",
              "delete:authentication_methods",
              "delete:branding",
              "delete:client_credentials",
              "delete:client_grants",
              "delete:clients",
              "delete:connections",
              "delete:custom_domains",
              "delete:device_credentials",
              "delete:email_provider",
              "delete:email_templates",
              "delete:grants",
              "delete:guardian_enrollments",
              "delete:integrations",
              "delete:log_streams",
              "delete:organization_connections",
              "delete:organization_invitations",
              "delete:organization_member_roles",
              "delete:organization_members",
              "delete:organizations",
              "delete:owners",
              "delete:requested_scopes",
              "delete:resource_servers",
              "delete:roles",
              "delete:rules",
              "delete:rules_configs",
              "delete:shields",
              "delete:tenant_invitations",
              "delete:tenant_members",
              "delete:tenants",
              "delete:users",
              "read:actions",
              "read:anomaly_blocks",
              "read:attack_protection",
              "read:authentication_methods",
              "read:branding",
              "read:checks",
              "read:client_credentials",
              "read:client_grants",
              "read:client_keys",
              "read:clients",
              "read:connections",
              "read:custom_domains",
              "read:device_credentials",
              "read:email_provider",
              "read:email_templates",
              "read:email_triggers",
              "read:entity_counts",
              "read:grants",
              "read:guardian_factors",
              "read:insights",
              "read:integrations",
              "read:log_streams",
              "read:logs",
              "read:mfa_policies",
              "read:organization_connections",
              "read:organization_invitations",
              "read:organization_member_roles",
              "read:organization_members",
              "read:organizations",
              "read:prompts",
              "read:requested_scopes",
              "read:resource_servers",
              "read:roles",
              "read:rules",
              "read:rules_configs",
              "read:shields",
              "read:signing_keys",
              "read:stats",
              "read:tenant_invitations",
              "read:tenant_members",
              "read:tenant_settings",
              "read:triggers",
              "read:users",
              "run:checks",
              "update:actions",
              "update:attack_protection",
              "update:authentication_methods",
              "update:branding",
              "update:client_credentials",
              "update:client_grants",
              "update:client_keys",
              "update:clients",
              "update:connections",
              "update:custom_domains",
              "update:email_provider",
              "update:email_templates",
              "update:email_triggers",
              "update:guardian_factors",
              "update:integrations",
              "update:log_streams",
              "update:mfa_policies",
              "update:organization_connections",
              "update:organizations",
              "update:prompts",
              "update:requested_scopes",
              "update:resource_servers",
              "update:roles",
              "update:rules",
              "update:rules_configs",
              "update:shields",
              "update:signing_keys",
              "update:tenant_members",
              "update:tenant_settings",
              "update:triggers",
              "update:users"
            ]
          },
          "strategy": "jwt",
          "user": {
            "email": "user.name@yourcompany.io",
            "name": "User Name",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "AfterAuthentication": false
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "patch",
        "path": "/api/v2/risk-assessment/config",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": {
          "AfterAuthentication": false,
          "BeforeLoginPrompt": false,
          "BeforeLoginPromptMonitoring": false
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230515215719063964000000000000001223372037488829643",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230515215719063964000000000000001223372037488829643",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-15 21:55:18.06",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-15 21:58:28.629",
  "p_row_id": "42b742dba9d5f3f284d49b971814",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Tenant Label"
}

Auth0 MFA Risk Assessment Enabled

#
Severity
informational
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 User enabled the mfa risk assessment setting for your organization's tenant.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    request_path = event.deep_get(
        "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
    )
    request_body = event.deep_get(
        "data", "details", "request", "body", "AfterAuthentication", default=[]
    )
    return all(
        [
            data_description == "Updates risk assessment configs",
            request_path == "/api/v2/risk-assessment/config",
            request_body is True,
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] enabled mfa risk assessment settings for your "
        f"organization’s tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 User enabled the mfa risk assessment setting for your organization's tenant.
DisplayName: "Auth0 MFA Risk Assessment Enabled"
Enabled: true
Filename: auth0_mfa_risk_assessment_enabled.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant when enabling this setting as it's in the best security interest for your organization's security posture.
Reference: https://auth0.com/docs/secure/multi-factor-authentication/enable-mfa#:~:text=Always%20policy%2C%20the-,MFA%20Risk%20Assessors,-section%20appears.%20By
Severity: Info
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.MFA.Risk.Assessment.Enabled"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Updates risk assessment configs
  • data.details.request.path is /api/v2/risk-assessment/config
  • data.details.request.body.AfterAuthentication is true
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant when enabling this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-15 21:55:18.060000000",
    "description": "Updates risk assessment configs",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "949869e066205b5076e6df203fdd7b9b",
            "scopes": [
              "create:actions",
              "create:actions_log_sessions",
              "create:authentication_methods",
              "create:client_credentials",
              "create:client_grants",
              "create:clients",
              "create:connections",
              "create:custom_domains",
              "create:email_provider",
              "create:email_templates",
              "create:guardian_enrollment_tickets",
              "create:integrations",
              "create:log_streams",
              "create:organization_connections",
              "create:organization_invitations",
              "create:organization_member_roles",
              "create:organization_members",
              "create:organizations",
              "create:requested_scopes",
              "create:resource_servers",
              "create:roles",
              "create:rules",
              "create:shields",
              "create:signing_keys",
              "create:tenant_invitations",
              "create:test_email_dispatch",
              "create:users",
              "delete:actions",
              "delete:anomaly_blocks",
              "delete:authentication_methods",
              "delete:branding",
              "delete:client_credentials",
              "delete:client_grants",
              "delete:clients",
              "delete:connections",
              "delete:custom_domains",
              "delete:device_credentials",
              "delete:email_provider",
              "delete:email_templates",
              "delete:grants",
              "delete:guardian_enrollments",
              "delete:integrations",
              "delete:log_streams",
              "delete:organization_connections",
              "delete:organization_invitations",
              "delete:organization_member_roles",
              "delete:organization_members",
              "delete:organizations",
              "delete:owners",
              "delete:requested_scopes",
              "delete:resource_servers",
              "delete:roles",
              "delete:rules",
              "delete:rules_configs",
              "delete:shields",
              "delete:tenant_invitations",
              "delete:tenant_members",
              "delete:tenants",
              "delete:users",
              "read:actions",
              "read:anomaly_blocks",
              "read:attack_protection",
              "read:authentication_methods",
              "read:branding",
              "read:checks",
              "read:client_credentials",
              "read:client_grants",
              "read:client_keys",
              "read:clients",
              "read:connections",
              "read:custom_domains",
              "read:device_credentials",
              "read:email_provider",
              "read:email_templates",
              "read:email_triggers",
              "read:entity_counts",
              "read:grants",
              "read:guardian_factors",
              "read:insights",
              "read:integrations",
              "read:log_streams",
              "read:logs",
              "read:mfa_policies",
              "read:organization_connections",
              "read:organization_invitations",
              "read:organization_member_roles",
              "read:organization_members",
              "read:organizations",
              "read:prompts",
              "read:requested_scopes",
              "read:resource_servers",
              "read:roles",
              "read:rules",
              "read:rules_configs",
              "read:shields",
              "read:signing_keys",
              "read:stats",
              "read:tenant_invitations",
              "read:tenant_members",
              "read:tenant_settings",
              "read:triggers",
              "read:users",
              "run:checks",
              "update:actions",
              "update:attack_protection",
              "update:authentication_methods",
              "update:branding",
              "update:client_credentials",
              "update:client_grants",
              "update:client_keys",
              "update:clients",
              "update:connections",
              "update:custom_domains",
              "update:email_provider",
              "update:email_templates",
              "update:email_triggers",
              "update:guardian_factors",
              "update:integrations",
              "update:log_streams",
              "update:mfa_policies",
              "update:organization_connections",
              "update:organizations",
              "update:prompts",
              "update:requested_scopes",
              "update:resource_servers",
              "update:roles",
              "update:rules",
              "update:rules_configs",
              "update:shields",
              "update:signing_keys",
              "update:tenant_members",
              "update:tenant_settings",
              "update:triggers",
              "update:users"
            ]
          },
          "strategy": "jwt",
          "user": {
            "email": "user.name@yourcompany.io",
            "name": "User Name",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "AfterAuthentication": true
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "patch",
        "path": "/api/v2/risk-assessment/config",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": {
          "AfterAuthentication": true,
          "BeforeLoginPrompt": false,
          "BeforeLoginPromptMonitoring": false
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230515215719063964000000000000001223372037488829643",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230515215719063964000000000000001223372037488829643"
}

Auth0 New Admin Invited

#
Severity
informational
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

A new admin invitation was issued.

MITRE ATT&CK coverage

TacticTechniques
Persistence

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    roles = event.deep_get("data", "details", "request", "body", "roles", default="<NO_ROLE_FOUND>")

    return all(
        [
            is_auth0_config_event(event),
            data_description == "Create tenant invitations for a given client",
            "owner" in roles,
        ]
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Filename: auth0_new_admin_invited.py
RuleID: Auth0.NewAdmin.Invitation
DisplayName: Auth0 New Admin Invited
Enabled: true
LogTypes:
  - Auth0.Events
Severity: Info
CreateAlert: false
Reports:
  MITRE ATT&CK:
    - TA0003:T1136
Description: A new admin invitation was issued.
Reference: 
  https://github.com/auth0/auth0-customer-detections/blob/main/detections/risk_of_tenant_takeover.yml

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.details.request.channel is https://manage.auth0.com/
  • data.description is Create tenant invitations for a given client
  • data.details.request.body.roles contains owner

Indicators

These rows show field, operator, and value matches.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-10 10:27:51.149000000",
    "description": "Create tenant invitations for a given client",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000311abf72f7a0ce7a303592"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77",
          "roles": [
            "owner",
            "user"
          ]
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/api/v2/integrations/installed",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "signup_pwd_leak",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452"
}

Auth0 New Admin Invited WITH Tenant Member Account Deletion

#
Severity
high
Time window
30h
Match by
p_alert_context.actor.email
Tags
Auth0
Source
github.com/panther-labs/panther-analysis

A user was invited as admin and shortly after deleted tenant member accounts. This may indicate account takeover attempts.

MITRE ATT&CK coverage

Rule specification

AnalysisType: correlation_rule
RuleID: "Auth0.AdminInvited.WITH.TenantMemberDeletion"
DisplayName: "Auth0 New Admin Invited WITH Tenant Member Account Deletion"
Enabled: false
Tags:
    - Auth0
Severity: High
Reports:
    MITRE ATT&CK:
        - TA0003:T1098
        - TA0003:T1136
Description: A user was invited as admin and shortly after deleted tenant member accounts. This may indicate account takeover attempts.
Detection:
    - Group:
        - ID: CreateAdmin
          RuleID: Auth0.NewAdmin.Invitation
        - ID: DeleteUser
          RuleID: Auth0.Delete.TenantMember
          MinMatchCount: 2
      MatchCriteria:
        field_name:
          - GroupID: CreateAdmin
            Match: p_alert_context.actor.email
          - GroupID: DeleteUser
            Match: p_alert_context.actor.email
      Schedule:
        RateMinutes: 1440
        TimeoutMinutes: 5
      LookbackWindowMinutes: 1800

Stages and Predicates

Fires when the steps below all occur within 30h, correlated by p_alert_context.actor.email. Each step needs one match unless a higher minimum is shown.

Stage 1: step CreateAdmin

References detection Auth0 New Admin Invited.

Stage 2: step DeleteUser

References detection Auth0 Delete Tenant Member (min 2 matches).

Auth0 Post Login Action Flow Updated

#
Severity
medium
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

An Auth0 User updated a post login action flow for your organization's tenant.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event
from panther_base_helpers import deep_get


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    request_path = event.deep_get(
        "data", "details", "request", "path", default="<NO_REQUEST_PATH_FOUND>"
    )

    return all(
        [
            data_description == "Update trigger bindings",
            request_path == "/api/v2/actions/triggers/post-login/bindings",
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    request_bindings = event.deep_get("data", "details", "request", "body", "bindings", default=[])
    response_bindings = event.deep_get(
        "data", "details", "response", "body", "bindings", default=[]
    )

    actions_added_list = []
    for binding in request_bindings:
        if "display_name" in binding:
            # check to see if actions were added to the flow
            actions_added_list.append(binding.get("display_name", ""))

    # otherwise, actions were removed from the action flow and we want
    # to grab what's still present in the flow
    actions_remaining_list = []
    for binding in response_bindings:
        if deep_get(binding, "display_name"):
            actions_remaining_list.append(
                deep_get(binding, "display_name", default="<NO_DISPLAYNAME>")
            )

    if actions_added_list:
        return (
            f"Auth0 User [{user}] added action(s) [{actions_added_list}] to a post-login action "
            f"flow for your organization’s tenant [{p_source_label}]."
        )

    if actions_remaining_list:
        return (
            f"Auth0 User [{user}] removed action(s) "
            f"to a post-login action flow for your organization’s tenant [{p_source_label}], "
            f"remaining actions include [{actions_remaining_list}]."
        )

    # no actions remain in the flow
    return (
        f"Auth0 User [{user}] removed all actions "
        f"from a post-login action flow for your organization’s tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: An Auth0 User updated a post login action flow for your organization's tenant.
DisplayName: "Auth0 Post Login Action Flow Updated"
Enabled: true
Filename: auth0_post_login_action_flow.py
Runbook: Assess if this was done by the user for a valid business reason. Be sure to replace any steps that were removed without authorization.
Reference: https://auth0.com/docs/customize/actions/flows-and-triggers/login-flow/api-object
Severity: Medium
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.Post.Login.Action.Flow"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Update trigger bindings
  • data.details.request.path is /api/v2/actions/triggers/post-login/bindings
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be sure to replace any steps that were removed without authorization.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "XXX",
    "client_name": "",
    "date": "2023-05-23 20:53:36.557000000",
    "description": "Update trigger bindings",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "XXX"
          },
          "strategy": "jwt",
          "user": {
            "email": "homer.simpson@yourcompany.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|XXX"
          }
        },
        "body": {
          "bindings": [
            {
              "display_name": "Password Rotation",
              "ref": {
                "type": "action_id",
                "value": "XXX"
              }
            }
          ]
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "patch",
        "path": "/api/v2/actions/triggers/post-login/bindings",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
      },
      "response": {
        "body": {
          "bindings": [
            {
              "action": {
                "all_changes_deployed": false,
                "created_at": "2023-04-24T19:33:44.217168082Z",
                "current_version": {
                  "created_at": "2023-05-11T17:26:53.569382908Z",
                  "id": "c4c1d580-2f51-4d7b-afa5-ad4216f40ad3",
                  "runtime": "node16",
                  "status": "BUILT",
                  "updated_at": "2023-05-11T17:26:53.724617041Z"
                },
                "deployed_version": {
                  "code": "",
                  "created_at": "2023-05-11T17:26:53.569382908Z",
                  "dependencies": [],
                  "deployed": true,
                  "id": "c4c1d580-2f51-4d7b-afa5-ad4216f40ad3",
                  "runtime": "node16",
                  "secrets": [],
                  "status": "built",
                  "updated_at": "2023-05-11T17:26:53.724617041Z"
                },
                "id": "XXX",
                "installed_integration_id": "XXX",
                "integration": {
                  "catalog_id": "password-rotation",
                  "created_at": "2023-04-24T19:33:44.212805393Z",
                  "current_release": {
                    "id": "",
                    "semver": {}
                  },
                  "description": "This Action allows you to configure the number of days a password is valid before it expires and the user must rotate it.\n",
                  "feature_type": "action",
                  "id": "64bee519-818f-4473-ab08-7c380f28da77",
                  "logo": "https://cdn.auth0.com/marketplace/catalog/content/assets/creators/auth0/auth0-avatar.png",
                  "name": "Password Rotation",
                  "partner_id": "XXX",
                  "short_description": "Enforce Users to Rotate Passwords",
                  "terms_of_use_url": "https://cdn.auth0.com/website/legal/files/mktplace/auth0-integration.pdf",
                  "updated_at": "2023-05-11T17:26:53.560940001Z",
                  "url_slug": "auth-0-password-rotation"
                },
                "name": "Password Rotation v1",
                "supported_triggers": [
                  {
                    "id": "post-login",
                    "status": "CURRENT",
                    "version": "v3"
                  }
                ],
                "updated_at": "2023-04-24T19:33:44.217168082Z"
              },
              "created_at": "2023-05-23T20:53:36.528608347Z",
              "display_name": "Password Rotation",
              "id": "a12b9e2a-ec0f-4060-b476-18547030088a",
              "trigger_id": "post-login",
              "updated_at": "2023-05-23T20:53:36.528608347Z"
            }
          ]
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "XXX",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "user_id": "google-oauth2|XXX"
  },
  "log_id": "XXX",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 Push Notification Fatigue

#
Severity
high
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

Push notifications threshold exceeded for a user. It may indicate a push notification fatigue attempt.

MITRE ATT&CK coverage

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_type = event.deep_get("data", "type", default="<NO_DATA_TYPE_FOUND>")

    return all(
        [
            data_type == "gd_send_pn",
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    return (
        f"Auth0 User [{user}] has received an excessive number of MFA push notifications,"
        f"possible MFA fatigue detected"
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: Push notifications threshold exceeded for a user. It may indicate a push notification fatigue attempt.
DisplayName: "Auth0 Push Notification Fatigue"
Enabled: true
Filename: auth0_push_notification_fatigue.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://github.com/auth0/auth0-customer-detections/tree/main/detections
Severity: High
Reports:
  MITRE ATT&CK:
    - TA0006:T1621
DedupPeriodMinutes: 30
LogTypes:
  - Auth0.Events
RuleID: "Auth0.PushNotification.Fatigue"
Threshold: 5

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.type is gd_send_pn
  • data.details.request.channel is https://manage.auth0.com/
Alert cadence
alerts after 5 matches within 30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-03 14:09:32.149000000",
    "description": "Push notification for MFA successfully sent",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000ecaf1bfbadb06900d22049"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "enabled": true
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/v2/attack-protection/push-notification",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": [],
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "gd_send_pn",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-23 20:47:51.149",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-23 20:49:28.671",
  "p_row_id": "00000000004a745ce33b57be383c543e",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 Rapid Dynamic Client Creation

#
Severity
high
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

Detects a spike in registered dynamic clients. This can indicate attempts to use such dynamic clients for malicious purposes.

MITRE ATT&CK coverage

TacticTechniques
Persistence

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    data_type = event.deep_get("data", "type", default="<NO_DATA_TYPE_FOUND>")

    return all(
        [
            is_auth0_config_event(event),
            data_type == "sapi",
            data_description == "Dynamic client registration",
        ]
    )


def title(event):

    client_id = event.deep_get(
        "data", "details", "response", "body", "client_id", default="<NO_CLIENT_ID_FOUND"
    )
    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")

    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 Significant number of Dynamic Client registration of [{data_description}] "
        f"with client id [{client_id}] in "
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
RuleID: "Auth0.Rapid.DynamicClient.Creation"
Filename: auth0_rapid_dynamic_client_creation.py
LogTypes:
  - Auth0.Events
DisplayName: "Auth0 Rapid Dynamic Client Creation"
Description: Detects a spike in registered dynamic clients. This can indicate attempts to use such dynamic clients for malicious purposes.
Severity: High
Reports:
  MITRE ATT&CK:
    - TA0003:T1136
Enabled: True
Reference: https://github.com/auth0/auth0-customer-detections/blob/main/detections/rapid_creation_of_clients_with_dynamic_registration.yml
DedupPeriodMinutes: 60
Threshold: 15

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.details.request.channel is https://manage.auth0.com/
  • data.type is sapi
  • data.description is Dynamic client registration
Alert cadence
alerts after 15 matches within 1h

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
descriptiondata.description
client_iddata.details.response.body.client_id
p_source_label

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-10 10:27:51.149000000",
    "description": "Dynamic client registration",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000311abf72f7a0ce7a303592"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/api/v2/integrations/installed",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": {
          "client_id": "64bee519-818f-4473-ab08-7c380f28da77",
          "integration_id": "64bee519-818f-4473-ab08-7c380f28da77"
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "sapi",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452"
}

Auth0 Refresh Token Reused

#
Severity
high
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

A refresh token was reused.

MITRE ATT&CK coverage

TacticTechniques
Credential Access

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    data_type = event.deep_get("data", "type", default="<NO_DATA_TYPE_FOUND>")

    return all(
        [
            data_description
            == "Unsuccessful Refresh Token exchange, reused refresh token detected",
            data_type == "ferrt",
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] attempted to reuse a refresh token for"
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: A refresh token was reused.
DisplayName: "Auth0 Refresh Token Reused"
Enabled: true
Filename: auth0_token_reuse.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://github.com/auth0/auth0-customer-detections/tree/main/detections
Severity: High
Reports:
  MITRE ATT&CK:
    - TA0006:T1528
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.RefreshToken.Reuse"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Unsuccessful Refresh Token exchange, reused refresh token detected
  • data.type is ferrt
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-03 14:09:32.149000000",
    "description": "Unsuccessful Refresh Token exchange, reused refresh token detected",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000ecaf1bfbadb06900d22049"
          },
          "strategy": "jwt",
          "user": {
            "email": "denethor@lotr.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "enabled": true
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "post",
        "path": "/v2/attack-protection/token-reuse",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": {
          "password_reset_policy": false,
          "passwordless_policy": false,
          "policy": false
        },
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "ferrt",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-23 20:47:51.149",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-23 20:49:28.671",
  "p_row_id": "00000000004a745ce33b57be383c543e",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 Same Phone Number Shared Across Multiple Users as MFA

#
Severity
high
Group by
data.details.authenticator.phone_number
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
github.com
Source
github.com/panther-labs/panther-analysis

Detecs when more than one user shares a phone number with another for MFA purposes. Attackers may register their phone number for multiple compromised accounts.

MITRE ATT&CK coverage

TacticTechniques
Persistence

Detection logic

from panther_auth0_helpers import auth0_alert_context


def rule(event):
    data_type = event.deep_get("data", "type", default="<NO_TYPE_FOUND>")
    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    phone_number = str(
        event.deep_get(
            "data", "details", "authenticator", "phone_number", default="<NO_PHONE_NUMBER_FOUND>"
        )
    )

    return (
        data_type == "gd_enrollment_complete"
        and data_description == "Guardian - Enrollment complete (sms)"
        and bool(phone_number)
    )


def unique(event):
    return event.deep_get("data", "user_id", default="")


def dedup(event):
    return str(
        event.deep_get(
            "data", "details", "authenticator", "phone_number", default="<NO_PHONE_NUMBER_FOUND>"
        )
    )


def title(event):
    user_id = event.deep_get("data", "user_id", default="<NO_USER_ID_FOUND>")
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    phone_number = event.deep_get(
        "data", "details", "authenticator", "phone_number", default="<NO_PHONE_NUMBER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] having user_id [{user_id}] "
        f"shares phone number [{phone_number}] as MFA in "
        f"your organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
Description: Detecs when more than one user shares a phone number with another for MFA purposes. Attackers may register their phone number for multiple compromised accounts.
DisplayName: "Auth0 Same Phone Number Shared Across Multiple Users as MFA"
Enabled: true
Filename: auth0_same_phone_mfa_multiple_users.py
Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.
Reference: https://github.com/auth0/auth0-customer-detections/tree/main/detections/multiple_phone_numbers_are_registered_as_mfa.yml
Severity: High
Reports:
  MITRE ATT&CK:
    - TA0003:T1098
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.SamePhone.MultipleUsers.MFA"
Threshold: 2

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.type is gd_enrollment_complete
  • data.description is Guardian - Enrollment complete (sms)
  • data.details.authenticator.phone_number is present
Alert cadence
alerts after 2 matches within 1h

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
user_iddata.user_id
phone_numberdata.details.authenticator.phone_number
p_source_label

Response runbook

Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2025-10-03 14:09:32.149000000",
    "description": "Guardian - Enrollment complete (sms)",
    "details": {
      "authenticator": {
        "phone_number": 1234567891
      },
      "request": {
        "auth": {
          "credentials": {
            "jti": "0000000000ecaf1bfbadb06900d22049"
          },
          "strategy": "jwt",
          "user": {
            "email": "eve@lexcorp.com",
            "name": "Homer Simpson"
          }
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36"
      },
      "response": {
        "body": [],
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230523204756343781000000000000001223372037583230452",
    "type": "gd_enrollment_complete",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/1.2.3.4 Safari/537.36",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230523204756343781000000000000001223372037583230452",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-23 20:47:51.149",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-23 20:49:28.671",
  "p_row_id": "00000000004a745ce33b57be383c543e",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}

Auth0 User Invitation Created

#
Severity
informational
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

Detection logic

import re

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event

org_re = re.compile(r"^/api/v2/organizations/[^/\s]+/invitations$")


def rule(event):
    if not is_auth0_config_event(event):
        return False

    return invitation_type(event) is not None


def title(event):
    inv_type = invitation_type(event)
    if inv_type == "tenant":
        try:
            invitee = event.deep_get("data", "details", "request", "body", "owners", default=[])[0]
        except IndexError:
            invitee = "<NO_INVITEE>"
    elif inv_type == "organization":
        invitee = event.deep_get("data", "details", "request", "body", "invitee", "email")
    else:
        invitee = "<NO_INVITEE>"

    inviter = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_INVITER>"
    )
    source = event.get("p_source_label", "<NO_PSOURCE>")
    return f"Auth0 User [{inviter}] invited [{invitee}] to {inv_type} [{source}]]"


def invitation_type(event):
    path = event.deep_get("data", "details", "request", "path", default="")

    if path == "/api/v2/tenants/invitations":
        return "tenant"
    if org_re.match(path):
        return "organization"

    return None


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
DisplayName: "Auth0 User Invitation Created"
Enabled: true
Filename: auth0_user_invitation_created.py
Reference: https://auth0.com/docs/manage-users/organizations/configure-organizations/invite-members
Severity: Info
CreateAlert: false
DedupPeriodMinutes: 60
LogTypes:
  - Auth0.Events
RuleID: "Auth0.User.Invitation.Created"
Threshold: 1

Stages and Predicates

Fires on Auth0.Events events when the condition below holds.

Condition

  • data.details.request.channel is https://manage.auth0.com/

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "_id": "90020230616045255729813000000000000001223372038324184656",
    "client_id": "6xNLmMWZMYvMO3ZjQoN8siUWAbg3pnpA",
    "client_name": "",
    "date": "2023-06-16T04:52:50.663Z",
    "description": "Create invitations to organization",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "81a67a5a3b2c4fb5cc2fcf38349456dd"
          },
          "strategy": "jwt",
          "user": {
            "email": "bob@panther.com",
            "name": "Bob",
            "user_id": "google-oauth2|115547599209686809398"
          }
        },
        "body": {
          "client_id": "KwJItGFu62zryEc4c8t5BQuwB1qdeDFa",
          "invitee": {
            "email": "larry@example.com"
          },
          "inviter": {
            "name": "Larry Jones"
          }
        },
        "channel": "https://manage.auth0.com/",
        "ip": "123.123.123.123",
        "method": "post",
        "path": "/api/v2/organizations/org_tFmw9RlOUjoSkOf1/invitations",
        "query": {},
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
      },
      "response": {
        "body": {
          "client_id": "KwJItGFu62zryEc4c8t5BQuwB1qdeDFa",
          "id": "uinv_DeLuEdgf3hjxRd0z",
          "invitee": {
            "email": "frank@example.com"
          },
          "inviter": {
            "name": "Bob Jones"
          }
        },
        "statusCode": 201
      }
    },
    "id": "90020230616045255729813000000000000001223372038324184656",
    "ip": "123.123.123.123",
    "isMobile": false,
    "log_id": "90020230616045255729813000000000000001223372038324184656",
    "type": "sapi",
    "user_agent": "Chrome 114.0.0 / Mac OS X 10.15.7",
    "user_id": "google-oauth2|115547599209686809398"
  },
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "auth0|6459776e974703f3a65dc258"
  ],
  "p_event_time": "2023-05-15 16:13:53.609",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-15 16:15:28.555",
  "p_row_id": "e20ac28001d19ac6df97b99618d4a207",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Auth0 Org Label"
}

Auth0 User Joined Tenant

#
Severity
informational
Entities
ip_addresses, usernames
Log types
Auth0.Events
Reference
auth0.com
Source
github.com/panther-labs/panther-analysis

User accepted invitation from Auth0 member to join an Auth0 tenant.

Detection logic

from panther_auth0_helpers import auth0_alert_context, is_auth0_config_event


def rule(event):

    data_description = event.deep_get("data", "description", default="<NO_DATA_DESCRIPTION_FOUND>")
    scopes = event.deep_get(
        "data",
        "details",
        "request",
        "auth",
        "credentials",
        "scopes",
        default=["<NO_CREDENTIAL_SCOPE>"],
    )
    state = event.deep_get("data", "details", "request", "body", "state", default="<NO_STATE>")
    return all(
        [
            data_description == "Update an invitation",
            "update:tenant_invitations" in scopes,
            state == "accepted",
            is_auth0_config_event(event),
        ]
    )


def title(event):
    user = event.deep_get(
        "data", "details", "request", "auth", "user", "email", default="<NO_USER_FOUND>"
    )
    p_source_label = event.get("p_source_label", "<NO_P_SOURCE_LABEL_FOUND>")
    return (
        f"Auth0 User [{user}] has accepted an invitation to join your "
        f"organization's tenant [{p_source_label}]."
    )


def alert_context(event):
    return auth0_alert_context(event)

Rule specification

AnalysisType: rule
DisplayName: Auth0 User Joined Tenant
Description: User accepted invitation from Auth0 member to join an Auth0 tenant.
Enabled: true
Filename: auth0_user_joined_tenant.py
RuleID: Auth0.User.Joined.Tenant
Reference: https://auth0.com/docs/manage-users/organizations/configure-organizations/invite-members#send-membership-invitations:~:text=.-,Send%20membership%20invitations,-You%20can
Severity: Info
CreateAlert: false
LogTypes:
  - Auth0.Events

Stages and Predicates

Fires on Auth0.Events events when all of the conditions below hold.

Condition

  • data.description is Update an invitation
  • data.details.request.auth.credentials.scopes contains update:tenant_invitations
  • data.details.request.body.state is accepted
  • data.details.request.channel is https://manage.auth0.com/

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
emaildata.details.request.auth.user.email
p_source_label

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "data": {
    "client_id": "1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr",
    "client_name": "",
    "date": "2023-05-15 16:17:00.128000000",
    "description": "Update an invitation",
    "details": {
      "request": {
        "auth": {
          "credentials": {
            "jti": "9da39f3d0b369356d2f4338ff13e4e8b",
            "scopes": [
              "update:tenant_invitations"
            ]
          },
          "strategy": "jwt",
          "user": {
            "email": "homer.simpson@yourcompany.com",
            "name": "Homer Simpson",
            "user_id": "google-oauth2|105261262156475850461"
          }
        },
        "body": {
          "state": "accepted",
          "user": {
            "email": "homer.simpson@yourcompany.com",
            "id": "google-oauth2|105261262156475850461"
          }
        },
        "channel": "https://manage.auth0.com/",
        "ip": "12.12.12.12",
        "method": "patch",
        "path": "/api/v2/tenants/invitations/inv_TEyzbreI336AHrfU",
        "query": {}
      },
      "response": {
        "body": {},
        "statusCode": 200
      }
    },
    "ip": "12.12.12.12",
    "log_id": "90020230515161703699125000000000000001223372037485126920",
    "type": "sapi",
    "user_id": "google-oauth2|105261262156475850461"
  },
  "log_id": "90020230515161703699125000000000000001223372037485126920",
  "p_any_ip_addresses": [
    "12.12.12.12"
  ],
  "p_any_usernames": [
    "google-oauth2|105261262156475850461"
  ],
  "p_event_time": "2023-05-15 16:17:00.128",
  "p_log_type": "Auth0.Events",
  "p_parse_time": "2023-05-15 16:18:28.605",
  "p_row_id": "6e94415d533cdcaac7ffc79618fb9b01",
  "p_schema_version": 0,
  "p_source_id": "b9031579-b2c5-45c2-b15c-632b995a4e36",
  "p_source_label": "Org Auth0 Tenant Label"
}