Detection rules › Panther
Panther rules: anthropic
Anthropic Admin API Key Created
#Detects when a new admin API key is created. Admin API keys have elevated privileges and their creation should be verified as authorized. The admin_api_key_id and scopes fields identify the key and its permissions.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "admin_api_key_created"
def title(event):
actor_email = anthropic_actor_id(event)
return f"Anthropic: Admin API key created by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Admin.API.Key.Created
DisplayName: "Anthropic Admin API Key Created"
Enabled: true
Filename: anthropic_admin_api_key_created.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects when a new admin API key is created. Admin API keys have elevated
privileges and their creation should be verified as authorized. The
admin_api_key_id and scopes fields identify the key and its permissions.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine admin work
2. Check if actor:email_address has created admin API keys in the past 90 days to determine if this is a first-time action
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Credential Access
Reports:
MITRE ATT&CK:
- TA0006:T1098.001 # Account Manipulation: Additional Cloud Credentials
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisadmin_api_key_created
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"admin_api_key_created" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine admin work
2. Check if actor:email_address has created admin API keys in the past 90 days to determine if this is a first-time action
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "admin_api_key_created"
}
Anthropic Admin API Key Deleted
#Detects when an admin API key is deleted. Unauthorized deletion could indicate an attacker revoking legitimate credentials to disrupt operations or covering tracks after using a compromised key.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "admin_api_key_deleted"
def title(event):
actor_email = anthropic_actor_id(event)
return f"Anthropic: Admin API key deleted by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Admin.API.Key.Deleted
DisplayName: "Anthropic Admin API Key Deleted"
Enabled: true
Filename: anthropic_admin_api_key_deleted.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects when an admin API key is deleted. Unauthorized deletion could
indicate an attacker revoking legitimate credentials to disrupt operations
or covering tracks after using a compromised key.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine key rotation
2. Check if an admin_api_key_created event occurred near this deletion to determine if this is a key rotation or a standalone deletion
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Credential Access
Reports:
MITRE ATT&CK:
- TA0006:T1098.001 # Account Manipulation: Additional Cloud Credentials
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisadmin_api_key_deleted
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"admin_api_key_deleted" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine key rotation
2. Check if an admin_api_key_created event occurred near this deletion to determine if this is a key rotation or a standalone deletion
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "admin_api_key_deleted"
}
Anthropic Excessive Chat Access Failures
#Detects when a single actor generates more than 50 chat access failures within a 10-minute window. Could indicate automated chat enumeration or unauthorized bulk access attempts. The claude_chat_id field identifies which chats were targeted — sequential or patterned IDs suggest scripted enumeration, while scattered IDs suggest shared-link browsing.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "claude_chat_access_failed"
def title(event):
return f"Anthropic: Excessive chat access failures from [{anthropic_actor_id(event)}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Excessive.Chat.Access.Failures
DisplayName: "Anthropic Excessive Chat Access Failures"
Enabled: true
Filename: anthropic_excessive_chat_access_failures.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Threshold: 50
DedupPeriodMinutes: 10
Description: >
Detects when a single actor generates more than 50 chat access failures
within a 10-minute window. Could indicate automated chat enumeration
or unauthorized bulk access attempts. The claude_chat_id field identifies
which chats were targeted — sequential or patterned IDs suggest scripted
enumeration, while scattered IDs suggest shared-link browsing.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 1 hour before and after the alert to establish whether this is part of normal browsing or an isolated burst
2. Compare the actor's claude_chat_access_failed count to their claude_chat_viewed count in the same window — a high failure-to-success ratio suggests enumeration rather than shared-link browsing
3. Check if actor:ip_address appears in threat intelligence feeds or is associated with known VPN/proxy services
Tags:
- Anthropic
- Access Control
- Enumeration
Reports:
MITRE ATT&CK:
- TA0007:T1087 # Account Discovery
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisclaude_chat_access_failed
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"claude_chat_access_failed" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 1 hour before and after the alert to establish whether this is part of normal browsing or an isolated burst
2. Compare the actor's claude_chat_access_failed count to their claude_chat_viewed count in the same window — a high failure-to-success ratio suggests enumeration rather than shared-link browsing
3. Check if actor:ip_address appears in threat intelligence feeds or is associated with known VPN/proxy services
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "user@example.com",
"ip_address": "192.168.1.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01XYZ"
},
"claude_chat_id": "chat_01ABC",
"created_at": "2026-04-28T08:00:00Z",
"id": "evt_01ABC123",
"organization_id": "org_123",
"type": "claude_chat_access_failed"
}
Anthropic Integration Connected
#Tracks when a user connects an external integration (e.g., GitHub, Google Drive) to their Anthropic account. Logged for compliance visibility into external data pathways. The integration_type field identifies which service was connected.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Collection |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "integration_user_connected"
def title(event):
actor_email = anthropic_actor_id(event)
integration_type = event.get("integration_type", "<UNKNOWN_TYPE>")
return f"Anthropic: User [{actor_email}] connected [{integration_type}] integration"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Integration.Connected
DisplayName: "Anthropic Integration Connected"
Enabled: true
Filename: anthropic_integration_connected.py
LogTypes:
- Anthropic.Activity
Severity: Info
Description: >
Tracks when a user connects an external integration (e.g., GitHub, Google Drive)
to their Anthropic account. Logged for compliance visibility into external data
pathways. The integration_type field identifies which service was connected.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 1 hour before and after the alert to understand the context of the integration connection
2. Check if actor:email_address has connected other integrations in the past 30 days to identify unusual patterns
3. Check if actor:ip_address matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Compliance
- Integrations
Reports:
MITRE ATT&CK:
- TA0009:T1530 # Data from Cloud Storage
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisintegration_user_connected
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"integration_user_connected" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
integration_type |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 1 hour before and after the alert to understand the context of the integration connection
2. Check if actor:email_address has connected other integrations in the past 30 days to identify unusual patterns
3. Check if actor:ip_address matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "user@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-06T17:38:28Z",
"id": "activity_01ABC123",
"integration_type": "github",
"organization_id": "org_01XYZ",
"type": "integration_user_connected"
}
Anthropic IP Restriction Deleted
#Detects when an organization IP restriction is deleted. IP restrictions are a critical network-level access control — removing them allows access from any IP address, which could indicate an attacker widening the attack surface after gaining admin access.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "org_ip_restriction_deleted"
def title(event):
actor_email = anthropic_actor_id(event)
return f"Anthropic: IP restriction deleted by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.IP.Restriction.Deleted
DisplayName: "Anthropic IP Restriction Deleted"
Enabled: true
Filename: anthropic_ip_restriction_deleted.py
LogTypes:
- Anthropic.Activity
Severity: High
Description: >
Detects when an organization IP restriction is deleted. IP restrictions
are a critical network-level access control — removing them allows access
from any IP address, which could indicate an attacker widening the attack
surface after gaining admin access.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 24 hours before the alert to identify any suspicious activity leading up to the IP restriction change
2. Check if actor:ip_address matches previously seen IP addresses for this actor in the past 30 days to detect potential account compromise
3. Check if other org_ip_restriction events (created, updated) occurred in the 1 hour around the alert to determine if this is a policy replacement or a standalone deletion
Tags:
- Anthropic
- Network Security
- Defense Evasion
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisorg_ip_restriction_deleted
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"org_ip_restriction_deleted" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 24 hours before the alert to identify any suspicious activity leading up to the IP restriction change
2. Check if actor:ip_address matches previously seen IP addresses for this actor in the past 30 days to detect potential account compromise
3. Check if other org_ip_restriction events (created, updated) occurred in the 1 hour around the alert to determine if this is a policy replacement or a standalone deletion
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "org_ip_restriction_deleted"
}
Anthropic MCP Server Created
#Detects when a new MCP (Model Context Protocol) server integration is created. Each MCP server is a new external data pathway that could be used for data exfiltration. Every new integration should be verified as approved, especially when created by external contractors or service accounts.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Exfiltration |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "mcp_server_created"
def title(event):
actor_email = anthropic_actor_id(event)
server_name = event.get("mcp_server_name", "<UNKNOWN_SERVER>")
return f"Anthropic: MCP server [{server_name}] created by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.MCP.Server.Created
DisplayName: "Anthropic MCP Server Created"
Enabled: true
Filename: anthropic_mcp_server_created.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects when a new MCP (Model Context Protocol) server integration is created.
Each MCP server is a new external data pathway that could be used for data
exfiltration. Every new integration should be verified as approved, especially
when created by external contractors or service accounts.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 1 hour before and after the alert to understand the context of the MCP server creation
2. Check if actor:email_address is an external contractor (ext. domain) or internal employee, and whether they have created MCP servers in the past 90 days
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Configuration
- Supply Chain
Reports:
MITRE ATT&CK:
- TA0010:T1567 # Exfiltration Over Web Service
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeismcp_server_created
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"mcp_server_created" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
mcp_server_name |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 1 hour before and after the alert to understand the context of the MCP server creation
2. Check if actor:email_address is an external contractor (ext. domain) or internal employee, and whether they have created MCP servers in the past 90 days
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "contractor@ext.example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-04-28T19:26:58Z",
"id": "activity_01ABC123",
"mcp_server_id": "mcpsrv_01ABC",
"mcp_server_name": "Snowflake",
"organization_id": "org_01XYZ",
"type": "mcp_server_created"
}
Anthropic MCP Server Deleted
#Detects when an MCP server integration is deleted from the organization. Removing an approved integration could indicate an attacker covering tracks or unauthorized configuration changes. The mcp_server_name and mcp_server_id fields identify which integration was removed.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "mcp_server_deleted"
def title(event):
actor_email = anthropic_actor_id(event)
server_name = event.get("mcp_server_name", "<UNKNOWN_SERVER>")
return f"Anthropic: MCP server [{server_name}] deleted by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.MCP.Server.Deleted
DisplayName: "Anthropic MCP Server Deleted"
Enabled: true
Filename: anthropic_mcp_server_deleted.py
LogTypes:
- Anthropic.Activity
Severity: Low
Description: >
Detects when an MCP server integration is deleted from the organization.
Removing an approved integration could indicate an attacker covering tracks
or unauthorized configuration changes. The mcp_server_name and mcp_server_id
fields identify which integration was removed.
Runbook: |
1. Find all Anthropic.Activity events with type mcp_server_created by actor:email_address in the 10 minutes after the alert to determine if this was a delete-then-recreate (config fix) or a standalone deletion
2. Check if actor:email_address has performed other administrative actions (claude_organization_settings_updated, mcp_server_created) in the 6 hours around the alert to assess if this is part of routine admin work
3. Find all alerts for actor:email_address in the past 7 days to check for signs of account compromise preceding this action
Tags:
- Anthropic
- Configuration
Reports:
MITRE ATT&CK:
- TA0005:T1562 # Impair Defenses
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeismcp_server_deleted
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"mcp_server_deleted" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
mcp_server_name |
Response runbook
1. Find all Anthropic.Activity events with type mcp_server_created by actor:email_address in the 10 minutes after the alert to determine if this was a delete-then-recreate (config fix) or a standalone deletion
2. Check if actor:email_address has performed other administrative actions (claude_organization_settings_updated, mcp_server_created) in the 6 hours around the alert to assess if this is part of routine admin work
3. Find all alerts for actor:email_address in the past 7 days to check for signs of account compromise preceding this action
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-05T21:46:28Z",
"id": "activity_01ABC123",
"mcp_server_id": "mcpsrv_01ABC",
"mcp_server_name": "Snowflake",
"organization_id": "org_01XYZ",
"type": "mcp_server_deleted"
}
Anthropic Organization Settings Updated
#Detects when organization-wide settings are modified in Anthropic. These changes can affect security posture for all users (e.g., SSO configuration, data retention, access controls). The updates field identifies which settings were changed.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
import re
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
PARENT_EVENT_TYPE = "claude_organization_settings_updated"
def rule(event):
return event.get("type") == PARENT_EVENT_TYPE
def _extract_update_type(entry_str):
"""Extract the first type value from a single serialized update entry."""
match = re.search(r"'type':\s*'([^']+)'", entry_str)
if not match:
match = re.search(r'"type":\s*"([^"]+)"', entry_str)
return match.group(1) if match else None
def _extract_update_types(updates):
"""Extract top-level update type values from the updates list.
Serializes each entry individually to avoid capturing type values
from nested objects. Uses string parsing because Panther's event
wrapper intercepts .get("type") on nested objects.
"""
result = []
for entry in updates:
update_type = _extract_update_type(str(entry))
if update_type and update_type != PARENT_EVENT_TYPE:
result.append(update_type)
return result
def title(event):
actor_email = anthropic_actor_id(event)
updates = event.get("updates", [])
if updates:
update_types = _extract_update_types(updates)
if update_types:
types_str = ", ".join(update_types)
return f"Anthropic: Organization settings updated by" f" [{actor_email}]: {types_str}"
return f"Anthropic: Organization settings updated by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Organization.Settings.Updated
DisplayName: "Anthropic Organization Settings Updated"
Enabled: true
Filename: anthropic_org_settings_updated.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects when organization-wide settings are modified in Anthropic. These changes
can affect security posture for all users (e.g., SSO configuration, data retention,
access controls). The updates field identifies which settings were changed.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to understand what other administrative actions they performed
2. Check if actor:email_address has performed claude_organization_settings_updated events in the past 90 days to determine if this is routine admin activity or a first-time action
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Configuration
Reports:
MITRE ATT&CK:
- TA0005:T1562 # Impair Defenses
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisclaude_organization_settings_updated
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"claude_organization_settings_updated" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to understand what other administrative actions they performed
2. Check if actor:email_address has performed claude_organization_settings_updated events in the past 90 days to determine if this is routine admin activity or a first-time action
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-04-29T09:14:15Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "claude_organization_settings_updated",
"updates": [
{
"current_value": [
{
"org_name": "example-org",
"type": "github"
}
],
"type": "vcs_connections"
}
]
}
Anthropic Organization User Deleted
#Tracks when a user is removed from the Anthropic organization. Logged for compliance visibility into user lifecycle changes. The deleted_user_id and deleted_user_email fields identify who was removed.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Impact |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "org_user_deleted"
def title(event):
actor_email = anthropic_actor_id(event)
deleted_user = event.get("deleted_user_email") or event.get("deleted_user_id", "<UNKNOWN_USER>")
return f"Anthropic: User [{deleted_user}] deleted from org by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Org.User.Deleted
DisplayName: "Anthropic Organization User Deleted"
Enabled: true
Filename: anthropic_org_user_deleted.py
LogTypes:
- Anthropic.Activity
Severity: Info
Description: >
Tracks when a user is removed from the Anthropic organization. Logged
for compliance visibility into user lifecycle changes. The deleted_user_id
and deleted_user_email fields identify who was removed.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine offboarding or an isolated deletion
2. Check if the deleted user had any unusual activity (claude_chat_access_failed, claude_organization_settings_updated) in the 7 days before removal
3. Check if actor:email_address has deleted other users in the past 7 days to identify potential bulk unauthorized removals
Tags:
- Anthropic
- Compliance
- User Lifecycle
Reports:
MITRE ATT&CK:
- TA0040:T1531 # Account Access Removal
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisorg_user_deleted
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"org_user_deleted" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
deleted_user_email |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine offboarding or an isolated deletion
2. Check if the deleted user had any unusual activity (claude_chat_access_failed, claude_organization_settings_updated) in the 7 days before removal
3. Check if actor:email_address has deleted other users in the past 7 days to identify potential bulk unauthorized removals
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"deleted_user_email": "deleted-user@example.com",
"deleted_user_id": "user_01DEF",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "org_user_deleted"
}
Anthropic Primary Owner Transferred
#Detects when the primary owner role of the Anthropic organization is transferred to another member. This is an extremely high-privilege action that gives full control of the organization. The previous_owner_id and new_owner_id fields identify who gave up and received ownership.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "primary_owner_transferred"
def title(event):
actor_email = anthropic_actor_id(event)
return f"Anthropic: Primary owner transferred by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Primary.Owner.Transferred
DisplayName: "Anthropic Primary Owner Transferred"
Enabled: true
Filename: anthropic_primary_owner_transferred.py
LogTypes:
- Anthropic.Activity
Severity: High
Description: >
Detects when the primary owner role of the Anthropic organization is
transferred to another member. This is an extremely high-privilege action
that gives full control of the organization. The previous_owner_id and
new_owner_id fields identify who gave up and received ownership.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 24 hours before the alert to identify any suspicious activity leading up to the ownership transfer
2. Check if actor:ip_address matches previously seen IP addresses for this actor in the past 30 days to detect potential account compromise
3. Find all alerts for actor:email_address in the past 7 days to check for signs of account compromise preceding this action
Tags:
- Anthropic
- Privilege Escalation
Reports:
MITRE ATT&CK:
- TA0003:T1098.003 # Account Manipulation: Additional Cloud Roles
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisprimary_owner_transferred
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"primary_owner_transferred" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 24 hours before the alert to identify any suspicious activity leading up to the ownership transfer
2. Check if actor:ip_address matches previously seen IP addresses for this actor in the past 30 days to detect potential account compromise
3. Find all alerts for actor:email_address in the past 7 days to check for signs of account compromise preceding this action
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "owner@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "primary_owner_transferred"
}
Anthropic Role Granted
#Tracks all role grants in the Anthropic organization. Currently used to build visibility into the role taxonomy as the log source matures. Once sufficient data is collected on org-level vs project-level role patterns, this rule can be refined to alert at higher severity for elevated roles.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "role_assignment_granted"
def title(event):
actor_email = anthropic_actor_id(event)
role = event.get("role", "<UNKNOWN_ROLE>")
target_id = event.get("target_id", "<UNKNOWN_TARGET>")
return f"Anthropic: Role [{role}] granted to [{target_id}] by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Role.Granted
DisplayName: "Anthropic Role Granted"
Enabled: true
Filename: anthropic_role_granted.py
LogTypes:
- Anthropic.Activity
Severity: Info
Description: >
Tracks all role grants in the Anthropic organization. Currently used to
build visibility into the role taxonomy as the log source matures. Once
sufficient data is collected on org-level vs project-level role patterns,
this rule can be refined to alert at higher severity for elevated roles.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine project creation or an isolated privilege grant
2. Check if target_id has been granted other roles in the past 7 days to identify potential privilege accumulation
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Access Control
Reports:
MITRE ATT&CK:
- TA0004:T1098 # Account Manipulation
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisrole_assignment_granted
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"role_assignment_granted" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
role | |
target_id |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine project creation or an isolated privilege grant
2. Check if target_id has been granted other roles in the past 7 days to identify potential privilege accumulation
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T13:02:42Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"resource_id": "claude_proj_01ABC",
"resource_type": "chat_project",
"role": "chat_project:viewer",
"target_id": "user_01DEF",
"target_type": "organization_member",
"type": "role_assignment_granted"
}
Anthropic Service Key Created
#Detects when a new service key is created. Service keys provide programmatic access and their creation should be verified as authorized. The service_key_id, service_name, key_name, and scopes fields identify the key and its permissions.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "service_key_created"
def title(event):
actor_email = anthropic_actor_id(event)
return f"Anthropic: Service key created by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Service.Key.Created
DisplayName: "Anthropic Service Key Created"
Enabled: true
Filename: anthropic_service_key_created.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects when a new service key is created. Service keys provide
programmatic access and their creation should be verified as authorized.
The service_key_id, service_name, key_name, and scopes fields identify
the key and its permissions.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine service account setup
2. Check if actor:email_address has created service keys in the past 90 days to determine if this is a first-time action
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Credential Access
Reports:
MITRE ATT&CK:
- TA0006:T1098.001 # Account Manipulation: Additional Cloud Credentials
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisservice_key_created
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"service_key_created" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine service account setup
2. Check if actor:email_address has created service keys in the past 90 days to determine if this is a first-time action
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "service_key_created"
}
Anthropic Service Key Revoked
#Detects when a service key is revoked. Unauthorized revocation could indicate an attacker disrupting integrations or covering tracks after using a compromised key. The service_key_id and service_name fields identify which key was revoked.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "service_key_revoked"
def title(event):
actor_email = anthropic_actor_id(event)
return f"Anthropic: Service key revoked by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Service.Key.Revoked
DisplayName: "Anthropic Service Key Revoked"
Enabled: true
Filename: anthropic_service_key_revoked.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects when a service key is revoked. Unauthorized revocation could
indicate an attacker disrupting integrations or covering tracks after
using a compromised key. The service_key_id and service_name fields
identify which key was revoked.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine key rotation or incident response
2. Check if a service_key_created event occurred near this revocation to determine if this is a key rotation or a standalone revocation
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Tags:
- Anthropic
- Credential Access
Reports:
MITRE ATT&CK:
- TA0006:T1098.001 # Account Manipulation: Additional Cloud Credentials
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisservice_key_revoked
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"service_key_revoked" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 6 hours before and after the alert to determine if this is part of routine key rotation or incident response
2. Check if a service_key_created event occurred near this revocation to determine if this is a key rotation or a standalone revocation
3. Check if actor:ip_address is associated with known VPN/proxy services or matches previously seen IP addresses for this actor
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "service_key_revoked"
}
Anthropic Spend Limit Deleted
#Detects when a platform spend limit is deleted. A deleted spend limit without a subsequent recreate could indicate an attacker removing financial guardrails to enable large-scale API usage or data exfiltration. Note that normal admin workflow often involves a delete immediately followed by a create (editing a limit).
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Impact |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "platform_spend_limit_deleted"
def title(event):
actor_email = anthropic_actor_id(event)
return f"Anthropic: Platform spend limit deleted by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.Spend.Limit.Deleted
DisplayName: "Anthropic Spend Limit Deleted"
Enabled: true
Filename: anthropic_spend_limit_deleted.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects when a platform spend limit is deleted. A deleted spend limit without
a subsequent recreate could indicate an attacker removing financial guardrails
to enable large-scale API usage or data exfiltration. Note that normal admin
workflow often involves a delete immediately followed by a create (editing a limit).
Runbook: |
1. Find all Anthropic.Activity events with type platform_spend_limit_created by actor:email_address in the 10 minutes after the alert to determine if this was a delete-then-recreate (normal edit) or a standalone deletion
2. Check if actor:email_address has performed other administrative actions (claude_organization_settings_updated, role_assignment_granted) in the 6 hours around the alert to assess if this is part of routine admin work
3. Find all alerts for actor:email_address in the past 7 days to check for signs of account compromise preceding this action
Tags:
- Anthropic
- Financial Controls
Reports:
MITRE ATT&CK:
- TA0040:T1496 # Resource Hijacking
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeisplatform_spend_limit_deleted
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"platform_spend_limit_deleted" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events with type platform_spend_limit_created by actor:email_address in the 10 minutes after the alert to determine if this was a delete-then-recreate (normal edit) or a standalone deletion
2. Check if actor:email_address has performed other administrative actions (claude_organization_settings_updated, role_assignment_granted) in the 6 hours around the alert to assess if this is part of routine admin work
3. Find all alerts for actor:email_address in the past 7 days to check for signs of account compromise preceding this action
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-04-30T09:46:26Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "platform_spend_limit_deleted"
}
Anthropic SSO Disabled
#Detects when SSO is disabled or an SSO connection is deactivated for the organization. Disabling SSO allows users to bypass the identity provider and use weaker authentication methods. This is a critical security posture change that could indicate an attacker attempting to maintain access without IdP visibility.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
event_type = event.get("type")
if event_type == "org_sso_toggled":
return event.get("is_enabled") in (False, "false")
if event_type == "org_sso_connection_deactivated":
return True
return False
def title(event):
actor_email = anthropic_actor_id(event)
event_type = event.get("type")
if event_type == "org_sso_toggled":
return f"Anthropic: SSO disabled by [{actor_email}]"
return f"Anthropic: SSO connection deactivated by [{actor_email}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.SSO.Disabled
DisplayName: "Anthropic SSO Disabled"
Enabled: true
Filename: anthropic_sso_disabled.py
LogTypes:
- Anthropic.Activity
Severity: High
Description: >
Detects when SSO is disabled or an SSO connection is deactivated for the
organization. Disabling SSO allows users to bypass the identity provider
and use weaker authentication methods. This is a critical security posture
change that could indicate an attacker attempting to maintain access
without IdP visibility.
Runbook: |
1. Find all Anthropic.Activity events by actor:email_address in the 24 hours before the alert to identify any suspicious activity leading up to the SSO change
2. Check if actor:ip_address matches previously seen IP addresses for this actor in the past 30 days to detect potential account compromise
3. Find all SSO-related events (sso_login_failed, sso_login_initiated, sso_login_succeeded) in the 1 hour before and after the alert to understand the authentication context
Tags:
- Anthropic
- Authentication
- Defense Evasion
Reports:
MITRE ATT&CK:
- TA0005:T1562.001 # Impair Defenses: Disable or Modify Tools
Stages and Predicates
Fires on Anthropic.Activity events when any of the conditions below holds.
Condition
any of:
typeisorg_sso_toggledall of:
typeis notorg_sso_toggledtypeisorg_sso_connection_deactivated
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.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq |
type | ne |
| field:"type" kind:ne value:"org_sso_toggled" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity events by actor:email_address in the 24 hours before the alert to identify any suspicious activity leading up to the SSO change
2. Check if actor:ip_address matches previously seen IP addresses for this actor in the past 30 days to detect potential account compromise
3. Find all SSO-related events (sso_login_failed, sso_login_initiated, sso_login_succeeded) in the 1 hour before and after the alert to understand the authentication context
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"email_address": "admin@example.com",
"ip_address": "10.0.0.1",
"type": "user_actor",
"user_agent": "Mozilla/5.0",
"user_id": "user_01ABC"
},
"created_at": "2026-05-07T10:00:00Z",
"id": "activity_01ABC123",
"is_enabled": false,
"organization_id": "org_01XYZ",
"type": "org_sso_toggled"
}
Anthropic SSO Login Failed
#Detects failed SSO login attempts to the Anthropic organization. The actor is unauthenticated so no email is available — only the source IP. Every failure is alerted on as SSO failures should be rare in normal operation.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Detection logic
from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context
def rule(event):
return event.get("type") == "sso_login_failed"
def title(event):
actor = anthropic_actor_id(event)
return f"Anthropic: SSO login failed from [{actor}]"
def dedup(event):
return anthropic_actor_id(event)
def alert_context(event):
return anthropic_alert_context(event)
Rule specification
AnalysisType: rule
RuleID: Anthropic.Activity.SSO.Login.Failed
DisplayName: "Anthropic SSO Login Failed"
Enabled: true
Filename: anthropic_sso_login_failed.py
LogTypes:
- Anthropic.Activity
Severity: Medium
Description: >
Detects failed SSO login attempts to the Anthropic organization. The actor
is unauthenticated so no email is available — only the source IP. Every
failure is alerted on as SSO failures should be rare in normal operation.
Runbook: |
1. Find all Anthropic.Activity SSO events (sso_login_initiated, sso_login_succeeded, sso_login_failed) from actor:ip_address in the 1 hour before and after the alert to determine if this was a one-off or part of a burst
2. Check if actor:ip_address appears in threat intelligence feeds or is associated with known VPN/proxy services
3. Check if actor:ip_address has been seen in successful sso_login_succeeded events in the past 30 days to determine if this is a known user IP
Tags:
- Anthropic
- Authentication
Reports:
MITRE ATT&CK:
- TA0006:T1110 # Brute Force
Stages and Predicates
Fires on Anthropic.Activity events when the condition below holds.
Condition
typeissso_login_failed
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type | eq |
| field:"type" kind:eq value:"sso_login_failed" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
event_type | type |
actor_type | actor.type |
actor_email | actor.email_address |
actor_user_id | actor.user_id |
ip_address | actor.ip_address |
user_agent | actor.user_agent |
api_key_id | actor.api_key_id |
organization_id | |
ips | p_any_ip_addresses |
Response runbook
1. Find all Anthropic.Activity SSO events (sso_login_initiated, sso_login_succeeded, sso_login_failed) from actor:ip_address in the 1 hour before and after the alert to determine if this was a one-off or part of a burst
2. Check if actor:ip_address appears in threat intelligence feeds or is associated with known VPN/proxy services
3. Check if actor:ip_address has been seen in successful sso_login_succeeded events in the past 30 days to determine if this is a known user IP
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"actor": {
"ip_address": "192.168.1.1",
"type": "unauthenticated_user_actor",
"user_agent": "Mozilla/5.0"
},
"created_at": "2026-05-05T21:33:29Z",
"id": "activity_01ABC123",
"organization_id": "org_01XYZ",
"type": "sso_login_failed"
}