diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dbba6f534c61e..5766eb69c6c42 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -243,6 +243,11 @@ datadog_checks_base/datadog_checks/base/checks/windows/ @DataDog/wi /adyen/manifest.json @DataDog/saas-integrations @DataDog/documentation /adyen/assets/logs/ @DataDog/saas-integrations @DataDog/documentation @DataDog/logs-integrations-reviewers +/anthropic_compliance_logs/ @DataDog/saas-integrations +/anthropic_compliance_logs/*.md @DataDog/saas-integrations @DataDog/documentation +/anthropic_compliance_logs/manifest.json @DataDog/saas-integrations @DataDog/documentation +/anthropic_compliance_logs/assets/logs/ @DataDog/saas-integrations @DataDog/documentation @DataDog/logs-integrations-reviewers + /authorize_net/ @DataDog/saas-integrations /authorize_net/*.md @DataDog/saas-integrations @DataDog/documentation /authorize_net/manifest.json @DataDog/saas-integrations @DataDog/documentation diff --git a/.github/workflows/config/labeler.yml b/.github/workflows/config/labeler.yml index 16eb1e1414360..0ea2917444c7a 100644 --- a/.github/workflows/config/labeler.yml +++ b/.github/workflows/config/labeler.yml @@ -101,6 +101,10 @@ integration/anthropic: - changed-files: - any-glob-to-any-file: - anthropic/**/* +integration/anthropic_compliance_logs: +- changed-files: + - any-glob-to-any-file: + - anthropic_compliance_logs/**/* integration/anthropic_usage_and_costs: - changed-files: - any-glob-to-any-file: diff --git a/anthropic_compliance_logs/CHANGELOG.md b/anthropic_compliance_logs/CHANGELOG.md new file mode 100644 index 0000000000000..a8856c0a7f6e9 --- /dev/null +++ b/anthropic_compliance_logs/CHANGELOG.md @@ -0,0 +1,7 @@ +# CHANGELOG - Anthropic Compliance Logs + +## 1.0.0 / 2026-05-13 + +***Added***: + +* Initial Release diff --git a/anthropic_compliance_logs/README.md b/anthropic_compliance_logs/README.md new file mode 100644 index 0000000000000..95673f37029e1 --- /dev/null +++ b/anthropic_compliance_logs/README.md @@ -0,0 +1,83 @@ +# Anthropic Compliance + +## Overview + +Datadog's Anthropic Compliance integration ingests audit activity logs from Anthropic's [Compliance API][1]. With this integration, security and compliance teams can: + +- **Monitor SSO sign-ins and authentication events** across your organization +- **Track API key lifecycle** (creation, deletion, scope updates) for Admin, Platform, and Scoped API keys +- **Audit Anthropic Console activity** including member invites, role changes, and workspace updates +- **Investigate Claude usage** at the audit level (chat views, project access, file operations) +- **Detect security-sensitive events** with the included Cloud SIEM detection rules + +The Compliance API is available to Anthropic Enterprise plan customers with the Compliance API enabled in their organization settings. + +## Setup + +### Prerequisites + +- An Anthropic **Enterprise plan** subscription +- **Compliance API enabled** in Anthropic Organization settings under **Data and privacy** +- An **Admin API key** (prefix `sk-ant-admin01-`) with the `read:compliance_activities` scope, or a dedicated **Compliance Access key** (prefix `sk-ant-api01-`) + +### 1. Enable the Compliance API in Anthropic + +1. Log in to the Anthropic Console as a Primary Owner. +2. Navigate to **Organization settings -> Data and privacy**. +3. Find the **Compliance API** section and click **Enable**. + +### 2. Generate or locate an Admin API key + +1. Navigate to **Organization settings -> API keys**. +2. Generate a new Admin API key, or use the existing key already configured for the [Anthropic Usage and Costs][2] integration (the same key is reused). +3. Copy the key to a secure location. + +### 3. Configure the Datadog integration + +1. In Datadog, go to [**Integrations -> Anthropic Compliance**](https://app.datadoghq.com/integrations?integrationId=anthropic-compliance-logs). +2. In the configuration panel, paste your **Admin API Key**. +3. Click **Save Configuration**. + +### 4. Validate + +1. Wait up to 5 minutes for the first crawl. +2. Open [Log Explorer][3] and filter on `source:anthropic-compliance-logs`. +3. Confirm logs appear with `evt.name` values such as `claude_chat_viewed`, `admin_api_key_created`, or `user_signed_in_sso`. + +## Data Collected + +### Logs + +The integration collects audit activity logs from `GET /v1/compliance/activities`. Each log includes: + +- A timestamp (`created_at`) with microsecond precision +- An actor (user, API key, SCIM, or system) with email, user ID, IP address, and User-Agent when applicable +- An activity `type` such as `user_signed_in_sso`, `admin_api_key_created`, `org_user_invite_accepted`, or `claude_chat_viewed` (150+ activity types across 35+ categories) +- Organization and workspace context + +Logs are tagged `source:anthropic-compliance-logs` and processed by a Datadog log pipeline that flattens the actor object into standard `usr.*` and `network.client.*` attributes and enriches the source IP with GeoIP and the User-Agent string. + +### Metrics + +Anthropic Compliance does not include any metrics. + +### Service Checks + +Anthropic Compliance does not include any service checks. + +### Events + +Anthropic Compliance does not include any events. + +## Troubleshooting + +- **No logs after 10 minutes**: Verify the Compliance API is enabled in Anthropic Organization settings under Data and privacy. +- **HTTP 403**: Confirm the Compliance API is enabled and that the Admin API key has the `read:compliance_activities` scope. +- **Enterprise gate**: The Compliance API is only available on the Enterprise plan. + +Need help? Contact [Datadog support][4]. + +[1]: https://platform.claude.com/docs/en/api/compliance +[2]: https://app.datadoghq.com/integrations?integrationId=anthropic-usage-and-costs +[3]: https://app.datadoghq.com/logs?query=source%3Aanthropic-compliance-logs +[4]: https://docs.datadoghq.com/help/ diff --git a/anthropic_compliance_logs/assets/account_config.json b/anthropic_compliance_logs/assets/account_config.json new file mode 100644 index 0000000000000..f1e63afad4f0d --- /dev/null +++ b/anthropic_compliance_logs/assets/account_config.json @@ -0,0 +1,19 @@ +{ + "supported_auth_methods": [], + "additional_config_fields": [ + { + "type": "password", + "key": "api_key", + "label": "Admin API key", + "help": "An Anthropic Admin API key with permission to read compliance logs. Generate one in the Anthropic Console under Settings > Admin Keys.", + "editable": true, + "required": true + } + ], + "dataflow_config": [ + { + "dataflow_id": "anthropic-compliance-logs", + "additional_config_fields": [] + } + ] +} diff --git a/anthropic_compliance_logs/assets/dashboards/anthropic_compliance_logs_overview.json b/anthropic_compliance_logs/assets/dashboards/anthropic_compliance_logs_overview.json new file mode 100644 index 0000000000000..4ff9cea3fd23b --- /dev/null +++ b/anthropic_compliance_logs/assets/dashboards/anthropic_compliance_logs_overview.json @@ -0,0 +1,665 @@ +{ + "title": "Anthropic Compliance Logs Overview", + "description": "Security and compliance visibility into Anthropic Console activity: SSO sign-ins, admin API key lifecycle, organization changes, and Claude chat/project access.", + "layout_type": "ordered", + "reflow_type": "fixed", + "is_read_only": false, + "notify_list": [], + "tags": ["integration:anthropic-compliance-logs"], + "template_variables": [ + { + "name": "org", + "prefix": "@organization_id", + "available_values": [], + "default": "*" + }, + { + "name": "actor_type", + "prefix": "@actor.type", + "available_values": [], + "default": "*" + }, + { + "name": "event_name", + "prefix": "@evt.name", + "available_values": [], + "default": "*" + } + ], + "widgets": [ + { + "definition": { + "title": "About Anthropic Compliance Logs", + "type": "group", + "background_color": "white", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "type": "image", + "url": "/static/images/logos/anthropic_large.svg", + "sizing": "contain", + "has_background": false, + "has_border": false, + "vertical_align": "center", + "horizontal_align": "center" + }, + "layout": {"x": 0, "y": 0, "width": 5, "height": 2} + }, + { + "definition": { + "type": "note", + "content": "## Anthropic Compliance Logs\n\nMonitor security-relevant activity from the Anthropic Console: SSO and password sign-ins, admin API key lifecycle, organization membership changes, SSO/SAML configuration updates, and Claude chat and project access events.\n\nAll widgets scope to `source:anthropic-compliance-logs`. Use the template variables at the top of the dashboard to slice by organization, actor type, or event name.\n\n### Useful links\n- [Anthropic Compliance Logs tile](https://app.datadoghq.com/integrations/anthropic-compliance-logs)\n- [Anthropic Console compliance API](https://docs.anthropic.com/en/api/compliance-api)\n- [Datadog Cloud SIEM](https://app.datadoghq.com/security)", + "background_color": "white", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": {"x": 0, "y": 2, "width": 5, "height": 4} + } + ] + }, + "layout": {"x": 0, "y": 0, "width": 5, "height": 7} + }, + { + "definition": { + "title": "Overview", + "type": "group", + "background_color": "vivid_blue", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "title": "Total compliance events", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "autoscale": true, + "precision": 0, + "timeseries_background": {"type": "bars"} + }, + "layout": {"x": 0, "y": 0, "width": 2, "height": 2} + }, + { + "definition": { + "title": "Unique actors", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [], + "compute": {"aggregation": "cardinality", "metric": "@usr.email"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "autoscale": true, + "precision": 0, + "timeseries_background": {"type": "bars"} + }, + "layout": {"x": 2, "y": 0, "width": 2, "height": 2} + }, + { + "definition": { + "title": "Unique source IPs", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [], + "compute": {"aggregation": "cardinality", "metric": "@network.client.ip"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "autoscale": true, + "precision": 0, + "timeseries_background": {"type": "bars"} + }, + "layout": {"x": 4, "y": 0, "width": 3, "height": 2} + }, + { + "definition": { + "title": "Events over time by event name", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": ["avg", "min", "max", "value", "sum"], + "type": "timeseries", + "requests": [ + { + "formulas": [{"formula": "query1", "alias": "events"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@evt.name", + "limit": 10, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "timeseries", + "style": {"palette": "dog_classic", "line_type": "solid", "line_width": "normal"}, + "display_type": "bars" + } + ] + }, + "layout": {"x": 0, "y": 2, "width": 7, "height": 3} + } + ] + }, + "layout": {"x": 5, "y": 0, "width": 7, "height": 7} + }, + { + "definition": { + "title": "Authentication & Geography", + "type": "group", + "background_color": "vivid_purple", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "type": "note", + "content": "Track sign-in activity across SSO, Google, Apple, and password flows. A spike in sign-outs without matching sign-ins, or sign-ins from unexpected countries, may indicate session hijacking or compromised credentials.", + "background_color": "purple", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": {"x": 0, "y": 0, "width": 12, "height": 1} + }, + { + "definition": { + "title": "Auth events timeline", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": ["avg", "min", "max", "value", "sum"], + "type": "timeseries", + "requests": [ + { + "formulas": [{"formula": "query1", "alias": "auth events"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs @evt.name:(user_signed_in_sso OR user_signed_in_google OR user_signed_in_apple OR user_signed_in_password OR user_signed_out) $org $actor_type"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@evt.name", + "limit": 10, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "timeseries", + "style": {"palette": "dog_classic", "line_type": "solid", "line_width": "normal"}, + "display_type": "bars" + } + ] + }, + "layout": {"x": 0, "y": 1, "width": 6, "height": 4} + }, + { + "definition": { + "title": "Sign-ins by country", + "title_size": "16", + "title_align": "left", + "type": "geomap", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs @evt.name:user_signed_in_* $org $actor_type"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@network.client.geoip.country.iso_code", + "limit": 250, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "style": {"palette": "hostmap_blues", "palette_flip": false}, + "view": {"focus": "WORLD"} + }, + "layout": {"x": 6, "y": 1, "width": 6, "height": 4} + } + ] + }, + "layout": {"x": 0, "y": 7, "width": 12, "height": 6} + }, + { + "definition": { + "title": "Event Breakdown", + "type": "group", + "background_color": "vivid_blue", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "type": "note", + "content": "Top event types and the kinds of actors generating them. A surge of `admin_api_key_actor` traffic, or unfamiliar event names, is worth investigating.", + "background_color": "blue", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": {"x": 0, "y": 0, "width": 12, "height": 1} + }, + { + "definition": { + "title": "Top event types", + "title_size": "16", + "title_align": "left", + "type": "toplist", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@evt.name", + "limit": 15, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "style": {"display": {"type": "stacked", "legend": "automatic"}} + }, + "layout": {"x": 0, "y": 1, "width": 6, "height": 4} + }, + { + "definition": { + "title": "Events by actor type", + "title_size": "16", + "title_align": "left", + "type": "sunburst", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs $org $event_name"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@actor.type", + "limit": 10, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar", + "style": {"palette": "datadog16"} + } + ], + "legend": {"type": "table"} + }, + "layout": {"x": 6, "y": 1, "width": 6, "height": 4} + } + ] + }, + "layout": {"x": 0, "y": 13, "width": 12, "height": 6} + }, + { + "definition": { + "title": "Identity & Access", + "type": "group", + "background_color": "white", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "title": "Top actors", + "title_size": "16", + "title_align": "left", + "type": "toplist", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs @usr.email:* $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@usr.email", + "limit": 15, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "style": {"display": {"type": "stacked", "legend": "automatic"}} + }, + "layout": {"x": 0, "y": 0, "width": 6, "height": 4} + }, + { + "definition": { + "title": "Top source IPs", + "title_size": "16", + "title_align": "left", + "type": "toplist", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs @network.client.ip:* $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@network.client.ip", + "limit": 15, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "style": {"display": {"type": "stacked", "legend": "automatic"}} + }, + "layout": {"x": 6, "y": 0, "width": 6, "height": 4} + } + ] + }, + "layout": {"x": 0, "y": 19, "width": 12, "height": 7} + }, + { + "definition": { + "title": "Security-Sensitive Activity", + "type": "group", + "background_color": "vivid_orange", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "type": "note", + "content": "API key lifecycle changes and per-organization activity volume. Unexpected key creation or deletion bursts, or activity from unknown organizations, should be reviewed against your change-management records.", + "background_color": "orange", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": {"x": 0, "y": 0, "width": 12, "height": 1} + }, + { + "definition": { + "title": "API key lifecycle events", + "title_size": "16", + "title_align": "left", + "type": "toplist", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs @evt.name:(*api_key_created OR *api_key_deleted OR *api_key_updated) $org $actor_type"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@evt.name", + "limit": 15, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "style": {"display": {"type": "stacked", "legend": "automatic"}} + }, + "layout": {"x": 0, "y": 1, "width": 6, "height": 4} + }, + { + "definition": { + "title": "Organization activity split", + "title_size": "16", + "title_align": "left", + "type": "toplist", + "requests": [ + { + "formulas": [{"formula": "query1"}], + "queries": [ + { + "name": "query1", + "data_source": "logs", + "search": {"query": "source:anthropic-compliance-logs $org $actor_type $event_name"}, + "indexes": ["*"], + "group_by": [ + { + "facet": "@organization_id", + "limit": 15, + "sort": {"aggregation": "count", "order": "desc"}, + "should_exclude_missing": true + } + ], + "compute": {"aggregation": "count"}, + "storage": "hot" + } + ], + "response_format": "scalar" + } + ], + "style": {"display": {"type": "stacked", "legend": "automatic"}} + }, + "layout": {"x": 6, "y": 1, "width": 6, "height": 4} + } + ] + }, + "layout": {"x": 0, "y": 26, "width": 12, "height": 6} + }, + { + "definition": { + "title": "Admin & SSO Activity Streams", + "type": "group", + "background_color": "vivid_pink", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "type": "note", + "content": "High-impact security events: actions taken by admin API keys and changes to SSO/SAML configuration. Each entry should map to a known operator or change ticket.", + "background_color": "pink", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": {"x": 0, "y": 0, "width": 12, "height": 1} + }, + { + "definition": { + "title": "Admin actions", + "title_size": "16", + "title_align": "left", + "type": "log_stream", + "indexes": ["*"], + "query": "source:anthropic-compliance-logs (@actor.type:admin_api_key_actor OR @evt.name:admin_*) $org $event_name", + "sort": {"column": "timestamp", "order": "desc"}, + "columns": ["host", "@evt.name", "@usr.email", "@network.client.ip"], + "show_date_column": true, + "show_message_column": true, + "message_display": "inline" + }, + "layout": {"x": 0, "y": 1, "width": 6, "height": 5} + }, + { + "definition": { + "title": "SSO and SAML config changes", + "title_size": "16", + "title_align": "left", + "type": "log_stream", + "indexes": ["*"], + "query": "source:anthropic-compliance-logs @evt.name:(*sso_* OR *saml_*) $org $actor_type", + "sort": {"column": "timestamp", "order": "desc"}, + "columns": ["host", "@evt.name", "@usr.email", "@network.client.ip"], + "show_date_column": true, + "show_message_column": true, + "message_display": "inline" + }, + "layout": {"x": 6, "y": 1, "width": 6, "height": 5} + } + ] + }, + "layout": {"x": 0, "y": 32, "width": 12, "height": 7} + }, + { + "definition": { + "title": "Recent Activity", + "type": "group", + "background_color": "white", + "show_title": true, + "layout_type": "ordered", + "widgets": [ + { + "definition": { + "title": "Recent compliance events", + "title_size": "16", + "title_align": "left", + "type": "log_stream", + "indexes": ["*"], + "query": "source:anthropic-compliance-logs $org $actor_type $event_name", + "sort": {"column": "timestamp", "order": "desc"}, + "columns": ["host", "@evt.name", "@actor.type", "@usr.email", "@network.client.geoip.country.iso_code"], + "show_date_column": true, + "show_message_column": true, + "message_display": "inline" + }, + "layout": {"x": 0, "y": 0, "width": 12, "height": 6} + } + ] + }, + "layout": {"x": 0, "y": 39, "width": 12, "height": 7} + } + ] +} diff --git a/anthropic_compliance_logs/assets/dataflows.yaml b/anthropic_compliance_logs/assets/dataflows.yaml new file mode 100644 index 0000000000000..399b61a46b909 --- /dev/null +++ b/anthropic_compliance_logs/assets/dataflows.yaml @@ -0,0 +1,6 @@ +provides: + - id: anthropic-compliance-logs + always_on: false + granular: true + data_type: logs + direction: inbound diff --git a/anthropic_compliance_logs/assets/logs/anthropic-compliance-logs.yaml b/anthropic_compliance_logs/assets/logs/anthropic-compliance-logs.yaml new file mode 100644 index 0000000000000..3c3b6c59ebe89 --- /dev/null +++ b/anthropic_compliance_logs/assets/logs/anthropic-compliance-logs.yaml @@ -0,0 +1,163 @@ +id: anthropic-compliance-logs +backend_only: false +facets: + - groups: + - Event + name: Event Name + path: evt.name + source: log + - groups: + - Web Access + name: User-Agent + path: http.useragent + source: log + - groups: + - Web Access + name: Browser + path: http.useragent_details.browser.family + source: log + - groups: + - Web Access + name: Device + path: http.useragent_details.device.family + source: log + - groups: + - Web Access + name: OS + path: http.useragent_details.os.family + source: log + - groups: + - Geoip + name: City Name + path: network.client.geoip.city.name + source: log + - groups: + - Geoip + name: Continent Code + path: network.client.geoip.continent.code + source: log + - groups: + - Geoip + name: Continent Name + path: network.client.geoip.continent.name + source: log + - groups: + - Geoip + name: Country ISO Code + path: network.client.geoip.country.iso_code + source: log + - groups: + - Geoip + name: Country Name + path: network.client.geoip.country.name + source: log + - groups: + - Geoip + name: Subdivision ISO Code + path: network.client.geoip.subdivision.iso_code + source: log + - groups: + - Geoip + name: Subdivision Name + path: network.client.geoip.subdivision.name + source: log + - groups: + - Web Access + name: Client IP + path: network.client.ip + source: log + - groups: + - Event + name: Actor ID + path: actor.id + source: log + - groups: + - Event + name: Actor Type + path: actor.type + source: log + - groups: + - User + name: User Email + path: usr.email + source: log + - groups: + - User + name: User ID + path: usr.id + source: log +pipeline: + type: pipeline + name: Anthropic Compliance Logs + enabled: true + filter: + query: source:anthropic-compliance-logs + processors: + - type: date-remapper + name: Define `created_at` as the official date of the log + enabled: true + sources: + - created_at + - type: attribute-remapper + name: Map `type` to `evt.name` + enabled: true + sources: + - type + sourceType: attribute + target: evt.name + targetType: attribute + preserveSource: false + overrideOnConflict: true + - type: attribute-remapper + name: Map `actor.email_address` to `usr.email` + enabled: true + sources: + - actor.email_address + sourceType: attribute + target: usr.email + targetType: attribute + preserveSource: false + overrideOnConflict: true + - type: attribute-remapper + name: Map `actor.user_id` to `usr.id` + enabled: true + sources: + - actor.user_id + sourceType: attribute + target: usr.id + targetType: attribute + preserveSource: false + overrideOnConflict: true + - type: attribute-remapper + name: Map `actor.ip_address` to `network.client.ip` + enabled: true + sources: + - actor.ip_address + sourceType: attribute + target: network.client.ip + targetType: attribute + preserveSource: false + overrideOnConflict: true + - type: attribute-remapper + name: Map `actor.user_agent` to `http.useragent` + enabled: true + sources: + - actor.user_agent + sourceType: attribute + target: http.useragent + targetType: attribute + preserveSource: false + overrideOnConflict: true + - type: geo-ip-parser + name: GeoIP parser on `network.client.ip` + enabled: true + sources: + - network.client.ip + target: network.client.geoip + - type: user-agent-parser + name: User-Agent parser on `http.useragent` + enabled: true + sources: + - http.useragent + target: http.useragent_details + encoded: false diff --git a/anthropic_compliance_logs/assets/logs/anthropic-compliance-logs_tests.yaml b/anthropic_compliance_logs/assets/logs/anthropic-compliance-logs_tests.yaml new file mode 100644 index 0000000000000..a2735c511d4dd --- /dev/null +++ b/anthropic_compliance_logs/assets/logs/anthropic-compliance-logs_tests.yaml @@ -0,0 +1,75 @@ +id: "anthropic-compliance-logs" +tests: + - + sample: |- + { + "actor" : { + "email_address" : "user@example.com", + "user_id" : "user_01FBY4qyk7SdPxJCAd4EfPbT", + "ip_address" : "192.0.2.1", + "type" : "user_actor", + "user_agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15" + }, + "organization_id" : "org_01GuSHHxdWNCcTtk6Wr5arBM", + "organization_uuid" : "80cb55fa-462c-4bc0-82d6-07ebb1a6f004", + "created_at" : "2026-05-05T16:04:57.150724Z", + "id" : "activity_01R1sBnxj7yvtdZnt8DsfpRL", + "type" : "claude_chat_viewed", + "claude_chat_id" : "claude_chat_01AxWT9aH4swoDJ8u6dShxMV" + } + service: "anthropic.compliance" + result: + custom: + actor: + type: "user_actor" + claude_chat_id: "claude_chat_01AxWT9aH4swoDJ8u6dShxMV" + created_at: "2026-05-05T16:04:57.150724Z" + evt: + name: "claude_chat_viewed" + http: + useragent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15" + useragent_details: + browser: + family: "Safari" + major: "17" + minor: "0" + device: + brand: "Apple" + category: "Desktop" + family: "Mac" + model: "Mac" + os: + family: "Mac OS X" + major: "10" + minor: "15" + patch: "7" + id: "activity_01R1sBnxj7yvtdZnt8DsfpRL" + network: + client: + geoip: {} + ip: "192.0.2.1" + organization_id: "org_01GuSHHxdWNCcTtk6Wr5arBM" + organization_uuid: "80cb55fa-462c-4bc0-82d6-07ebb1a6f004" + usr: + email: "user@example.com" + id: "user_01FBY4qyk7SdPxJCAd4EfPbT" + message: |- + { + "actor" : { + "email_address" : "user@example.com", + "user_id" : "user_01FBY4qyk7SdPxJCAd4EfPbT", + "ip_address" : "192.0.2.1", + "type" : "user_actor", + "user_agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15" + }, + "organization_id" : "org_01GuSHHxdWNCcTtk6Wr5arBM", + "organization_uuid" : "80cb55fa-462c-4bc0-82d6-07ebb1a6f004", + "created_at" : "2026-05-05T16:04:57.150724Z", + "id" : "activity_01R1sBnxj7yvtdZnt8DsfpRL", + "type" : "claude_chat_viewed", + "claude_chat_id" : "claude_chat_01AxWT9aH4swoDJ8u6dShxMV" + } + service: "anthropic.compliance" + tags: + - "source:LOGS_SOURCE" + timestamp: 1777997097150 diff --git a/anthropic_compliance_logs/assets/monitors/anthropic_compliance_logs_no_data.json b/anthropic_compliance_logs/assets/monitors/anthropic_compliance_logs_no_data.json new file mode 100644 index 0000000000000..54a3a7aa693e8 --- /dev/null +++ b/anthropic_compliance_logs/assets/monitors/anthropic_compliance_logs_no_data.json @@ -0,0 +1,35 @@ +{ + "version": 2, + "created_at": "2026-05-08", + "last_updated_at": "2026-05-08", + "title": "Compliance log ingestion has stopped", + "description": "Alerts when no Anthropic compliance log events are received within a recent window, indicating the crawler is broken, the Compliance API toggle was disabled, or the Admin API key lost compliance scope.", + "tags": [ + "integration:anthropic-compliance-logs" + ], + "definition": { + "id": 1, + "name": "[Anthropic] Compliance log ingestion has stopped", + "type": "log alert", + "query": "logs(\"source:anthropic-compliance-logs\").index(\"*\").rollup(\"count\").last(\"1h\") < 1", + "message": "{{#is_alert}}\n## What's happening?\n\nNo Anthropic compliance log events have been received in the last 1 hour. The Anthropic crawler normally polls every 5 minutes, so an hour of complete silence is a strong signal that compliance log ingestion has stopped.\n{{/is_alert}}\n\n{{#is_warning}}\n## What's happening?\n\nNo Anthropic compliance log events have been received in the last 30 minutes. The Anthropic crawler normally polls every 5 minutes, so this gap may indicate an early sign of an ingestion problem.\n{{/is_warning}}\n\n{{#is_recovery}}\n## Recovered\n\nAnthropic compliance log ingestion has resumed. Events tagged `source:anthropic-compliance-logs` are flowing again.\n{{/is_recovery}}\n\n{{^is_recovery}}\n\n---\n\n## Impact\n\nWhile compliance logs are not being ingested, your organization loses visibility into Anthropic Console activity (member changes, workspace and API key management, billing actions, and other audit events) — which can create gaps in security review, incident response, and regulatory evidence.\n\n---\n\n## Common causes\n\n* **Compliance API was disabled** — Someone toggled off the Compliance API in the Anthropic Organization settings under Data and privacy.\n* **Admin API key was rotated or lost scope** — The Admin API key configured in Datadog was rotated, revoked, or no longer carries the `read:compliance_activities` scope.\n* **Anthropic Compliance API outage** — An upstream incident on Anthropic's Compliance API is preventing the crawler from retrieving events.\n\n---\n\n## How to investigate\n\n* Open the [Log Explorer scoped to Anthropic compliance logs](/logs?query=source%3Aanthropic-compliance-logs) and confirm there is no recent activity.\n* Review the Anthropic Compliance Logs integration README for setup and troubleshooting steps.\n* In the Anthropic Console, go to **Settings -> Data and privacy** and confirm the Compliance API is enabled for the organization.\n* On the Datadog Anthropic Compliance Logs tile, verify the configured Admin API key is current.\n* Confirm the Admin API key still has the `read:compliance_activities` scope; rotate and re-enter the key in Datadog if necessary.\n* Check the [Anthropic status page](https://status.anthropic.com/) for any active Compliance API incidents.\n\n---\n\n## Related links\n\n* [Anthropic Compliance Logs integration documentation](https://docs.datadoghq.com/integrations/anthropic_compliance_logs/)\n* [Anthropic status page](https://status.anthropic.com/)\n{{/is_recovery}}", + "options": { + "thresholds": { + "critical": 1 + }, + "enable_logs_sample": true, + "notify_audit": false, + "require_full_window": false, + "notify_no_data": false, + "renotify_interval": 0, + "include_tags": true, + "on_missing_data": "default", + "avalanche_window": 10, + "groupby_simple_monitor": false, + "silenced": {} + }, + "priority": 3, + "restricted_roles": null + }, + "template_variables": [] +} diff --git a/anthropic_compliance_logs/assets/saved_views/all_anthropic_compliance_logs.json b/anthropic_compliance_logs/assets/saved_views/all_anthropic_compliance_logs.json new file mode 100644 index 0000000000000..aef8181d5897e --- /dev/null +++ b/anthropic_compliance_logs/assets/saved_views/all_anthropic_compliance_logs.json @@ -0,0 +1,38 @@ +{ + "name": "All Anthropic Compliance Logs", + "type": "logs", + "page": "stream", + "query": "source:anthropic-compliance-logs", + "timerange": { + "interval_ms": 86400000 + }, + "visible_facets": [ + "core_service", + "tag_source", + "core_host", + "core_status", + "log_evt.name", + "log_actor.type", + "log_actor.id", + "log_usr.email", + "log_usr.id", + "log_network.client.ip", + "log_network.client.geoip.country.iso_code" + ], + "options": { + "columns": [ + "source", + "service", + "@evt.name", + "@actor.type", + "@usr.email", + "@network.client.ip", + "host" + ], + "sort": "desc", + "show_date_column": true, + "message_display": "inline", + "show_message_column": false, + "show_timeline": true + } +} diff --git a/anthropic_compliance_logs/assets/saved_views/anthropic_admin_activity.json b/anthropic_compliance_logs/assets/saved_views/anthropic_admin_activity.json new file mode 100644 index 0000000000000..5fd66831f48a3 --- /dev/null +++ b/anthropic_compliance_logs/assets/saved_views/anthropic_admin_activity.json @@ -0,0 +1,35 @@ +{ + "name": "Anthropic Admin Activity", + "type": "logs", + "page": "stream", + "query": "source:anthropic-compliance-logs @actor.type:admin_api_key_actor", + "timerange": { + "interval_ms": 86400000 + }, + "visible_facets": [ + "core_service", + "tag_source", + "core_status", + "log_evt.name", + "log_actor.type", + "log_actor.id", + "log_usr.email", + "log_network.client.ip" + ], + "options": { + "columns": [ + "source", + "service", + "@evt.name", + "@actor.type", + "@usr.email", + "@network.client.ip", + "host" + ], + "sort": "desc", + "show_date_column": true, + "message_display": "inline", + "show_message_column": false, + "show_timeline": true + } +} diff --git a/anthropic_compliance_logs/assets/saved_views/anthropic_api_key_lifecycle.json b/anthropic_compliance_logs/assets/saved_views/anthropic_api_key_lifecycle.json new file mode 100644 index 0000000000000..7412a29f19e24 --- /dev/null +++ b/anthropic_compliance_logs/assets/saved_views/anthropic_api_key_lifecycle.json @@ -0,0 +1,35 @@ +{ + "name": "Anthropic API Key Lifecycle", + "type": "logs", + "page": "stream", + "query": "source:anthropic-compliance-logs @evt.name:(*api_key_created OR *api_key_deleted OR *api_key_updated OR *api_key_rotated)", + "timerange": { + "interval_ms": 86400000 + }, + "visible_facets": [ + "core_service", + "tag_source", + "core_status", + "log_evt.name", + "log_actor.type", + "log_actor.id", + "log_usr.email", + "log_network.client.ip" + ], + "options": { + "columns": [ + "source", + "service", + "@evt.name", + "@actor.type", + "@usr.email", + "@network.client.ip", + "host" + ], + "sort": "desc", + "show_date_column": true, + "message_display": "inline", + "show_message_column": false, + "show_timeline": true + } +} diff --git a/anthropic_compliance_logs/assets/saved_views/anthropic_auth_events.json b/anthropic_compliance_logs/assets/saved_views/anthropic_auth_events.json new file mode 100644 index 0000000000000..b992d023e95b2 --- /dev/null +++ b/anthropic_compliance_logs/assets/saved_views/anthropic_auth_events.json @@ -0,0 +1,34 @@ +{ + "name": "Anthropic Auth Events", + "type": "logs", + "page": "stream", + "query": "source:anthropic-compliance-logs @evt.name:(user_signed_in_sso OR user_signed_in_google OR user_signed_in_apple OR user_signed_out OR user_signed_in_*)", + "timerange": { + "interval_ms": 86400000 + }, + "visible_facets": [ + "core_service", + "tag_source", + "core_status", + "log_evt.name", + "log_usr.email", + "log_network.client.ip", + "log_network.client.geoip.country.iso_code" + ], + "options": { + "columns": [ + "source", + "service", + "@evt.name", + "@usr.email", + "@network.client.ip", + "@network.client.geoip.country.iso_code", + "host" + ], + "sort": "desc", + "show_date_column": true, + "message_display": "inline", + "show_message_column": false, + "show_timeline": true + } +} diff --git a/anthropic_compliance_logs/assets/saved_views/anthropic_org_membership_changes.json b/anthropic_compliance_logs/assets/saved_views/anthropic_org_membership_changes.json new file mode 100644 index 0000000000000..74237dcdd2a9d --- /dev/null +++ b/anthropic_compliance_logs/assets/saved_views/anthropic_org_membership_changes.json @@ -0,0 +1,35 @@ +{ + "name": "Anthropic Org Membership Changes", + "type": "logs", + "page": "stream", + "query": "source:anthropic-compliance-logs @evt.name:(org_user_invite_sent OR org_user_invite_accepted OR org_user_invite_revoked OR org_user_role_changed OR org_user_removed)", + "timerange": { + "interval_ms": 86400000 + }, + "visible_facets": [ + "core_service", + "tag_source", + "core_status", + "log_evt.name", + "log_actor.type", + "log_actor.id", + "log_usr.email", + "log_network.client.ip" + ], + "options": { + "columns": [ + "source", + "service", + "@evt.name", + "@actor.type", + "@usr.email", + "@network.client.ip", + "host" + ], + "sort": "desc", + "show_date_column": true, + "message_display": "inline", + "show_message_column": false, + "show_timeline": true + } +} diff --git a/anthropic_compliance_logs/assets/service_checks.json b/anthropic_compliance_logs/assets/service_checks.json new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/anthropic_compliance_logs/assets/service_checks.json @@ -0,0 +1 @@ +[] diff --git a/anthropic_compliance_logs/manifest.json b/anthropic_compliance_logs/manifest.json new file mode 100644 index 0000000000000..82f9170d62643 --- /dev/null +++ b/anthropic_compliance_logs/manifest.json @@ -0,0 +1,58 @@ +{ + "manifest_version": "2.0.0", + "app_uuid": "eafbb640-db8c-4ab5-94db-6bc2b80a071d", + "app_id": "anthropic-compliance-logs", + "owner": "saas-integrations", + "display_on_public_website": false, + "tile": { + "overview": "README.md#Overview", + "configuration": "README.md#Setup", + "support": "README.md#Troubleshooting", + "changelog": "CHANGELOG.md", + "description": "Collect compliance logs from Anthropic for security monitoring and SIEM use cases.", + "title": "Anthropic Compliance", + "media": [], + "classifier_tags": [ + "Category::AI/ML", + "Category::Log Collection", + "Category::Security", + "Submitted Data Type::Logs", + "Supported OS::Linux", + "Supported OS::Windows", + "Supported OS::macOS", + "Offering::Integration" + ] + }, + "assets": { + "integration": { + "auto_install": false, + "source_type_id": 78505088, + "source_type_name": "Anthropic Compliance", + "events": { + "creates_events": false + }, + "service_checks": { + "metadata_path": "assets/service_checks.json" + } + }, + "dashboards": { + "Anthropic Compliance Logs Overview": "assets/dashboards/anthropic_compliance_logs_overview.json" + }, + "monitors": { + "Anthropic Compliance Log Ingestion Has Stopped": "assets/monitors/anthropic_compliance_logs_no_data.json" + }, + "saved_views": { + "All Anthropic Compliance Logs": "assets/saved_views/all_anthropic_compliance_logs.json", + "Anthropic Auth Events": "assets/saved_views/anthropic_auth_events.json", + "Anthropic API Key Lifecycle": "assets/saved_views/anthropic_api_key_lifecycle.json", + "Anthropic Admin Activity": "assets/saved_views/anthropic_admin_activity.json", + "Anthropic Org Membership Changes": "assets/saved_views/anthropic_org_membership_changes.json" + } + }, + "author": { + "support_email": "help@datadoghq.com", + "name": "Datadog", + "homepage": "https://www.datadoghq.com", + "sales_email": "info@datadoghq.com" + } +} diff --git a/http_check/changelog.d/23731.added b/http_check/changelog.d/23731.added new file mode 100644 index 0000000000000..c235626fccf57 --- /dev/null +++ b/http_check/changelog.d/23731.added @@ -0,0 +1 @@ +Add http_status_code tag to http metrics. diff --git a/http_check/datadog_checks/http_check/http_check.py b/http_check/datadog_checks/http_check/http_check.py index 776a61d08304d..157b83a181bc4 100644 --- a/http_check/datadog_checks/http_check/http_check.py +++ b/http_check/datadog_checks/http_check/http_check.py @@ -183,6 +183,9 @@ def send_status_down(loginfo, down_msg): raise else: + if r is not None: + http_status = r.status_code + tags_list.append("http_status_code:{}".format(http_status)) if use_cert_from_response: peer_cert = r.raw.connection.sock.getpeercert(binary_form=True) diff --git a/http_check/tests/test_http_integration.py b/http_check/tests/test_http_integration.py index cd927ca673615..e3a52268ef3f1 100644 --- a/http_check/tests/test_http_integration.py +++ b/http_check/tests/test_http_integration.py @@ -430,11 +430,16 @@ def test_data_methods(aggregator, http_check): url_tag = ['url:{}'.format(instance.get('url'))] instance_tag = ['instance:{}'.format(instance.get('name'))] + http_status_tag = ['http_status_code:{}'.format('200')] aggregator.assert_service_check(HTTPCheck.SC_STATUS, status=AgentCheck.OK, tags=url_tag + instance_tag, count=1) - aggregator.assert_metric('network.http.can_connect', tags=url_tag + instance_tag, value=1.0, count=1) - aggregator.assert_metric('network.http.cant_connect', tags=url_tag + instance_tag, value=0.0, count=1) - aggregator.assert_metric('network.http.response_time', tags=url_tag + instance_tag, count=1) + aggregator.assert_metric( + 'network.http.can_connect', tags=url_tag + instance_tag + http_status_tag, value=1.0, count=1 + ) + aggregator.assert_metric( + 'network.http.cant_connect', tags=url_tag + instance_tag + http_status_tag, value=0.0, count=1 + ) + aggregator.assert_metric('network.http.response_time', tags=url_tag + instance_tag + http_status_tag, count=1) # Assert coverage for this check on this instance aggregator.assert_all_metrics_covered() diff --git a/kafka/README.md b/kafka/README.md index 90c6c341d6901..cb5959f23f287 100644 --- a/kafka/README.md +++ b/kafka/README.md @@ -2,12 +2,12 @@ ![Kafka Dashboard][1] +**New:** [Kafka Monitoring][24] tracks consumer lag, throughput, schemas, and adds message reading capabilities. + ## Overview View Kafka broker metrics and logs for a 360-view of the health and performance of your Kafka clusters in real time. -Add [Data Streams Monitoring][24] to your producers and consumers to visualize the application topology, root cause issues across services, and measure end to end latency, throughput and lag. - **Note**: - This check has a limit of 350 metrics per instance. The number of returned metrics is indicated in the Agent status output. Specify the metrics you are interested in by editing the configuration below. For more detailed instructions on customizing the metrics to collect, see the @@ -25,8 +25,6 @@ To collect Kafka consumer metrics, see the [kafka_consumer check][3]. The Agent's Kafka check is included in the [Datadog Agent][4] package, no additional installation is needed on your Kafka nodes. -Add [Data Streams Monitoring][24] to your producers and consumers to visualize the application topology, root cause issues across services, and measure end to end latency, throughput and lag. - The check collects metrics from JMX with [JMXFetch][5]. A JVM is needed on each kafka node so the Agent can run JMXFetch. The same JVM that Kafka uses can be used for this. **Note**: The Kafka check cannot be used with Managed Streaming for Apache Kafka (Amazon MSK). Use the [Amazon MSK integration][6] instead. @@ -184,5 +182,4 @@ See [service_checks.json][15] for a list of service checks provided by this inte [21]: https://www.datadoghq.com/blog/monitor-kafka-with-datadog [22]: https://raw.githubusercontent.com/DataDog/dd-agent/5.2.1/conf.d/kafka.yaml.example [23]: https://www.datadoghq.com/knowledge-center/apache-kafka/ -[24]: https://docs.datadoghq.com/data_streams/ -[25]: /data-streams +[24]: https://docs.datadoghq.com/data_streams/kafka?utm_source=docs&utm_medium=callout&utm_campaign=DocsCTA-DSMKafka-IntegrationsKafka