Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@
/packages/cyera @elastic/security-service-integrations @elastic/sit-crest-contractors
/packages/cylance @elastic/security-service-integrations @elastic/sit-crest-contractors
/packages/darktrace @elastic/security-service-integrations @elastic/sit-crest-contractors
/packages/datadog @elastic/integration-experience
/packages/dataminr_pulse @elastic/security-service-integrations @elastic/sit-crest-contractors
/packages/ded @elastic/sec-applied-ml @elastic/kibana-management
/packages/dga @elastic/sec-applied-ml
Expand Down
3 changes: 3 additions & 0 deletions packages/datadog/_dev/build/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies:
ecs:
reference: "git@v9.4.0"
56 changes: 56 additions & 0 deletions packages/datadog/_dev/build/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Datadog Audit Logs

Collects the Datadog audit trail from an S3 bucket written by
[Datadog Log Archives](https://docs.datadoghq.com/logs/log_configuration/archives/),
using SQS object-created notifications for near-real-time delivery.

## Data flow

1. In Datadog, configure a Logs Archive with the query `source:audit`, targeting
an S3 bucket. Datadog writes gzipped NDJSON objects to a date-partitioned
prefix (`dt=YYYYMMDD/hour=HH/archive_*.json.gz`), one audit event per line.
2. Configure an S3 event notification on that bucket for `s3:ObjectCreated:*`,
delivering to an SQS queue.
3. Point this integration at the bucket ARN and the SQS queue URL.

If no queue URL is supplied, the integration falls back to polling the bucket on
the configured interval. SQS is strongly preferred — polling re-lists the bucket
on every interval and does not scale with archive volume.

## Required AWS permissions

- `s3:GetObject` on the archive prefix
- `s3:ListBucket` on the bucket (polling mode only)
- `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:GetQueueAttributes` on the queue

Prefer `role_arn` over static access keys.

## Data stream

`datadog.audit` — all audit surfaces (API requests, workflows, agent
configuration changes, dashboards, organization management, MCP server calls,
audit-trail queries) in one stream.

## Notable fields

| Field | Description |
|---|---|
| `datadog.event.name` | Datadog product surface (`Request`, `Workflows`, `Dashboard`, …) |
| `datadog.action` | Raw Datadog verb (`accessed`, `modified`, `created`, …) |
| `event.action` | Composite `<surface>_<verb>`, e.g. `dashboard_modified` |
| `datadog.route.path` | Templated API route — aggregate on this, not `url.path`, which contains IDs |
| `datadog.actor.type` | `USER`, `SYSTEM`, or `SERVICE_ACCOUNT` |
| `datadog.auth_method` | `SESSION`, `SYSTEM`, `API_AND_APP_KEY`, `OAUTH_TOKEN` |
| `datadog.threat_intel.*` | Datadog's Spur-sourced IP enrichment, including VPN/proxy tunnel detail |
| `datadog.asset.new_value` / `.prev_value` | `flattened` before/after blobs for configuration changes |
| `datadog.metadata` | `flattened` catch-all for surface-specific metadata |
| `related.user` | Every actor identifier in the event, including API key and OAuth client IDs |

`datadog.asset.new_value`, `datadog.asset.prev_value`, `datadog.metadata`, and `datadog.threat_intel` are
`flattened`. They are queryable in KQL and DSL by subkey, but **not** in ES|QL,
which hard-errors on `flattened`. Stable dimensions are lifted into typed
sibling fields for that reason.

## Dashboard

![Datadog Audit Logs Dashboard](../img/Datadog_dashboard.png)
Comment thread
hnguyen-coreweave marked this conversation as resolved.
5 changes: 5 additions & 0 deletions packages/datadog/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- version: "0.1.0"
changes:
- description: Initial release of the Datadog audit logs integration (S3 via SQS, full ECS mapping)
type: enhancement
link: https://github.com/elastic/integrations/pull/20526
Comment thread
hnguyen-coreweave marked this conversation as resolved.
Comment thread
hnguyen-coreweave marked this conversation as resolved.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions packages/datadog/data_stream/audit/agent/stream/aws-s3.yml.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{{#if bucket_list_prefix}}
bucket_list_prefix: {{bucket_list_prefix}}
{{/if}}
{{#if region}}
region: {{region}}
{{/if}}

# Collection mode
{{#if collection_mode}}
{{#contains "sqs" collection_mode}}
# SQS Configuration (real-time mode)
{{#if queue_url}}
queue_url: {{queue_url}}
{{/if}}
{{#if visibility_timeout}}
visibility_timeout: {{visibility_timeout}}
{{/if}}
{{#if max_number_of_messages}}
max_number_of_messages: {{max_number_of_messages}}
{{/if}}
{{/contains}}
{{#contains "polling" collection_mode}}
# Polling Configuration (interval mode)
# S3 Bucket Configuration
{{#if bucket_arn}}
bucket_arn: {{bucket_arn}}
{{/if}}
{{#if interval}}
bucket_list_interval: {{bucket_list_interval}}
{{/if}}
{{/contains}}
{{else}}
# Backward-compatible fallback when collection_mode is not present.
{{#if queue_url}}
# SQS Configuration (real-time mode)
queue_url: {{queue_url}}
{{#if visibility_timeout}}
visibility_timeout: {{visibility_timeout}}
{{/if}}
{{#if max_number_of_messages}}
max_number_of_messages: {{max_number_of_messages}}
{{/if}}
{{else}}
# Polling Configuration (interval mode)
{{#if interval}}
bucket_list_interval: {{bucket_list_interval}}
{{/if}}
{{/if}}
{{/if}}

# AWS Credentials
{{#if access_key_id}}
access_key_id: {{access_key_id}}
{{/if}}
{{#if secret_access_key}}
secret_access_key: {{secret_access_key}}
{{/if}}
{{#if session_token}}
session_token: {{session_token}}
{{/if}}
{{#if role_arn}}
role_arn: {{role_arn}}
{{/if}}

# File Processing
{{#if file_selectors}}
file_selectors:
{{{file_selectors}}}
{{else}}
file_selectors:
- regex: '.*\.json\.gz$'
{{#if max_bytes}}
max_bytes: {{max_bytes}}
{{/if}}
{{/if}}

# Performance & Concurrency
{{#if number_of_workers}}
number_of_workers: {{number_of_workers}}
{{/if}}
{{#if api_timeout}}
api_timeout: {{api_timeout}}
{{/if}}
{{#if fips_enabled}}
fips_enabled: {{fips_enabled}}
{{/if}}

tags:
{{#each tags as |tag|}}
- {{tag}}
{{/each}}
{{#if preserve_original_event}}
- preserve_original_event
{{/if}}

processors:
Comment thread
hnguyen-coreweave marked this conversation as resolved.
{{#if processors}}
{{processors}}
{{/if}}

# Disable host enrichment
publisher_pipeline.disable_host: true
Loading