Anthropic Artifact Shared Publicly


Description

Detects when an artifact's sharing audience is changed to public. Public artifacts are accessible to anyone with the link, which could expose sensitive content outside the organization.

Query · python

from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context


def rule(event):
    if event.get("type") != "claude_artifact_sharing_updated":
        return False
    audience = event.get("audience")
    if audience is None:
        return False
    # Panther's event wrapper intercepts .get("type") and ["type"] on nested
    # objects, returning the parent event's type. String matching on the
    # serialized audience is the only reliable approach in the test framework.
    # In production, audience entries only have a "type" key, so matching
    # "'public'" or '"public"' is equivalent to checking entry.type == "public".
    audience_str = str(audience)
    return "'public'" in audience_str or '"public"' in audience_str


def title(event):
    actor_email = anthropic_actor_id(event)
    artifact_id = event.get("claude_artifact_id", "<UNKNOWN_ARTIFACT>")
    return f"Anthropic: Artifact [{artifact_id}] shared publicly by [{actor_email}]"


def dedup(event):
    return anthropic_actor_id(event)


def alert_context(event):
    return anthropic_alert_context(event)

Analyst notes

  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 sharing change
  2. Check if the claude_artifact_id has been viewed or accessed by external users in the 24 hours after the sharing change
  3. Check if actor:email_address has shared other artifacts publicly in the past 30 days to determine if this is a pattern
Raw source Anthropic Artifact Shared Publicly · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
RuleID: Anthropic.Activity.Artifact.Shared.Publicly
DisplayName: "Anthropic Artifact Shared Publicly"
Enabled: true
Filename: anthropic_artifact_shared_publicly.py
LogTypes:
  - Anthropic.Activity
Severity: Medium
Description: >
  Detects when an artifact's sharing audience is changed to public. Public
  artifacts are accessible to anyone with the link, which could expose
  sensitive content outside the organization.
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 sharing change
  2. Check if the claude_artifact_id has been viewed or accessed by external users in the 24 hours after the sharing change
  3. Check if actor:email_address has shared other artifacts publicly in the past 30 days to determine if this is a pattern
Tags:
  - Anthropic
  - Data Loss Prevention
Reports:
  MITRE ATT&CK:
    - TA0010:T1567  # Exfiltration Over Web Service
Tests:
  - Name: Artifact shared publicly
    ExpectedResult: true
    Log:
      {
        "id": "activity_01ABC123",
        "created_at": "2026-05-07T09:10:01Z",
        "organization_id": "org_01XYZ",
        "type": "claude_artifact_sharing_updated",
        "claude_artifact_id": "claude_artifact_01ABC",
        "audience": [{"type": "public"}],
        "actor": {
          "type": "user_actor",
          "email_address": "user@example.com",
          "user_id": "user_01ABC",
          "ip_address": "10.0.0.1",
          "user_agent": "Mozilla/5.0"
        }
      }
  - Name: Artifact shared with organization only
    ExpectedResult: false
    Log:
      {
        "id": "activity_01DEF456",
        "created_at": "2026-05-07T09:10:01Z",
        "organization_id": "org_01XYZ",
        "type": "claude_artifact_sharing_updated",
        "claude_artifact_id": "claude_artifact_01DEF",
        "audience": [{"type": "organization"}],
        "actor": {
          "type": "user_actor",
          "email_address": "user@example.com",
          "user_id": "user_01DEF",
          "ip_address": "10.0.0.2"
        }
      }
  - Name: Non-matching event type
    ExpectedResult: false
    Log:
      {
        "id": "activity_01GHI789",
        "created_at": "2026-05-07T09:10:01Z",
        "organization_id": "org_01XYZ",
        "type": "claude_chat_created",
        "actor": {
          "type": "user_actor",
          "email_address": "user@example.com",
          "user_id": "user_01GHI",
          "ip_address": "10.0.0.3"
        }
      }


# ------ paired body: anthropic_artifact_shared_publicly.py ------

from panther_anthropic_helpers import anthropic_actor_id, anthropic_alert_context


def rule(event):
    if event.get("type") != "claude_artifact_sharing_updated":
        return False
    audience = event.get("audience")
    if audience is None:
        return False
    # Panther's event wrapper intercepts .get("type") and ["type"] on nested
    # objects, returning the parent event's type. String matching on the
    # serialized audience is the only reliable approach in the test framework.
    # In production, audience entries only have a "type" key, so matching
    # "'public'" or '"public"' is equivalent to checking entry.type == "public".
    audience_str = str(audience)
    return "'public'" in audience_str or '"public"' in audience_str


def title(event):
    actor_email = anthropic_actor_id(event)
    artifact_id = event.get("claude_artifact_id", "<UNKNOWN_ARTIFACT>")
    return f"Anthropic: Artifact [{artifact_id}] shared publicly by [{actor_email}]"


def dedup(event):
    return anthropic_actor_id(event)


def alert_context(event):
    return anthropic_alert_context(event)

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.