Databricks User Account Deleted


Description

Detects user account deletions in Databricks. While often part of normal offboarding processes, unauthorized deletions could indicate malicious activity or insider threats. Successful deletions are elevated to HIGH severity.

Query · python

from panther_databricks_helpers import databricks_alert_context


def rule(event):
    if event.get("serviceName") != "accounts":
        return False

    if event.get("actionName") != "delete":
        return False

    # Only match user deletions, not other account-level deletes
    # Primary check: targetUserName field exists
    # Fallback: endpoint contains "/users/" or starts with "users"
    if event.deep_get("requestParams", "targetUserName") is not None:
        return True

    endpoint = event.deep_get("requestParams", "endpoint", default="").lower()
    return "/users/" in endpoint or endpoint.startswith("users")


def severity(event):
    status_code = event.deep_get("response", "statusCode")
    return "HIGH" if status_code == 200 else "LOW"


def title(event):
    target_user = event.deep_get("requestParams", "targetUserName", default="Unknown User")
    actor = event.deep_get("userIdentity", "email", default="Unknown Actor")
    status_code = event.deep_get("response", "statusCode")
    status = "Success" if status_code == 200 else "Failed"
    return f"User account deletion {status}: {target_user} by {actor}"


def dedup(event):
    target_user = event.deep_get("requestParams", "targetUserName", default="unknown")
    return f"user_deleted_{target_user}"


def alert_context(event):
    return databricks_alert_context(
        event,
        additional_fields={
            "target_user": event.deep_get("requestParams", "targetUserName"),
            "endpoint": event.deep_get("requestParams", "endpoint"),
        },
    )

Analyst notes

  1. Query audit logs for all actions performed by the deleted user (requestParams.targetUserName) in the 48 hours before deletion
  2. Check if there were any privilege escalation or suspicious actions by this user in the 7 days before deletion
  3. Find all user deletions by this actor in the past 30 days to identify bulk deletion patterns
Raw source Databricks User Account Deleted · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
Filename: databricks_user_account_deleted.py
RuleID: "Databricks.Audit.UserAccountDeleted"
DisplayName: "Databricks User Account Deleted"
Enabled: true
Status: Experimental
LogTypes:
  - Databricks.Audit
Tags:
  - Databricks
  - Impact
Reports:
  MITRE ATT&CK:
    - TA0040:T1531 # Account Access Removal
Severity: Low
Description: >
  Detects user account deletions in Databricks. While often part of normal offboarding processes,
  unauthorized deletions could indicate malicious activity or insider threats. Successful deletions
  are elevated to HIGH severity.
Runbook: |
  1. Query audit logs for all actions performed by the deleted user (requestParams.targetUserName) in the 48 hours before deletion
  2. Check if there were any privilege escalation or suspicious actions by this user in the 7 days before deletion
  3. Find all user deletions by this actor in the past 30 days to identify bulk deletion patterns
Reference: https://github.com/databricks-solutions/cybersec-workspace-detection-app/blob/main/base/detections/event-based/user_account_deleted.py
Tests:
  - Name: Successful User Deletion
    ExpectedResult: true
    Log:
      timestamp: 1234567890000
      serviceName: "accounts"
      actionName: "delete"
      userIdentity:
        email: "admin@example.com"
      sourceIPAddress: "198.51.100.1"
      requestParams:
        targetUserName: "user@example.com"
        endpoint: "/users"
      response:
        statusCode: 200
  - Name: Failed User Deletion
    ExpectedResult: true
    Log:
      timestamp: 1234567890000
      serviceName: "accounts"
      actionName: "delete"
      userIdentity:
        email: "admin@example.com"
      sourceIPAddress: "198.51.100.1"
      requestParams:
        targetUserName: "user@example.com"
        endpoint: "/users"
      response:
        statusCode: 403
  - Name: Wrong Service
    ExpectedResult: false
    Log:
      timestamp: 1234567890000
      serviceName: "workspace"
      actionName: "delete"
      userIdentity:
        email: "admin@example.com"
  - Name: Delete Without User Context
    ExpectedResult: false
    Log:
      timestamp: 1234567890000
      serviceName: "accounts"
      actionName: "delete"
      userIdentity:
        email: "admin@example.com"
      requestParams:
        endpoint: "/servicePrincipals"
      response:
        statusCode: 200
  - Name: Different Action
    ExpectedResult: false
    Log:
      timestamp: 1234567890000
      serviceName: "accounts"
      actionName: "create"
      userIdentity:
        email: "admin@example.com"


# ------ paired body: databricks_user_account_deleted.py ------

from panther_databricks_helpers import databricks_alert_context


def rule(event):
    if event.get("serviceName") != "accounts":
        return False

    if event.get("actionName") != "delete":
        return False

    # Only match user deletions, not other account-level deletes
    # Primary check: targetUserName field exists
    # Fallback: endpoint contains "/users/" or starts with "users"
    if event.deep_get("requestParams", "targetUserName") is not None:
        return True

    endpoint = event.deep_get("requestParams", "endpoint", default="").lower()
    return "/users/" in endpoint or endpoint.startswith("users")


def severity(event):
    status_code = event.deep_get("response", "statusCode")
    return "HIGH" if status_code == 200 else "LOW"


def title(event):
    target_user = event.deep_get("requestParams", "targetUserName", default="Unknown User")
    actor = event.deep_get("userIdentity", "email", default="Unknown Actor")
    status_code = event.deep_get("response", "statusCode")
    status = "Success" if status_code == 200 else "Failed"
    return f"User account deletion {status}: {target_user} by {actor}"


def dedup(event):
    target_user = event.deep_get("requestParams", "targetUserName", default="unknown")
    return f"user_deleted_{target_user}"


def alert_context(event):
    return databricks_alert_context(
        event,
        additional_fields={
            "target_user": event.deep_get("requestParams", "targetUserName"),
            "endpoint": event.deep_get("requestParams", "endpoint"),
        },
    )

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.