Skip to content

[AWS] Add Amazon EKS audit data stream - #21051

Open
bryans3c wants to merge 3 commits into
mainfrom
aws-eks-audit-data-stream
Open

[AWS] Add Amazon EKS audit data stream#21051
bryans3c wants to merge 3 commits into
mainfrom
aws-eks-audit-data-stream

Conversation

@bryans3c

@bryans3c bryans3c commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Adds the aws.eks_audit data stream to the AWS integration to collect Amazon EKS Kubernetes API audit logs from CloudWatch Logs, parallel to how the azure and gcp packages expose provider-native Kubernetes audit streams. Without this, EKS audit events are only reachable through the provider-neutral kubernetes.audit_logs stream, so AWS-native detection rules have no logs-aws.* index to target and no aws.eks.audit.* schema to query.

Proposed commit message

aws: add eks_audit data stream

Add a dedicated data stream for Amazon EKS Kubernetes API audit logs delivered to CloudWatch Logs by EKS control-plane logging.

The aws-cloudwatch input discovers the EKS log group by ARN, name, or the /aws/eks/ prefix (precedence ARN > name > prefix) and selects kube-apiserver-audit log streams. The ingest pipeline parses each audit.k8s.io Event into aws.eks.audit.*, derives event.outcome from the authorization decision with an HTTP-status fallback, sets ECS event.category/type from the verb and subresource, and projects user, source, user_agent, orchestrator, cloud, and related fields.

Request and response bodies are stored with dynamic: false so arbitrary CRD content cannot grow the mapping; only declared fields (pod spec security settings, RBAC rules, roleRef, subjects, images) are indexed and the full body stays in _source. Secret and SecretList payload values are redacted, including last-applied-configuration annotations. Malformed or unsupported records become searchable pipeline_error documents instead of being routed to the failure store.

This provides the AWS-native ingestion path needed by AWS EKS detection rules, mirroring the existing GKE and AKS provider-native rule sets. It complements the kubernetes integration's provider-neutral CloudWatch input rather than replacing it.

Checklist

  • I have reviewed tips for building integrations and this pull request is aligned with them.
  • I have verified that all data streams collect metrics or logs.
  • I have added an entry to my package's changelog.yml file.
  • I have verified that Kibana version constraints are current according to guidelines.
  • I have verified that any added dashboard complies with Kibana's Dashboard good practicesN/A, no dashboards added.

Author's Checklist

  • All pipeline fixtures are synthetic (account 123456789012, RFC 5737 IPs, placeholder users and cluster names). No real account IDs, ARNs, IPs, or identities.
  • elastic-package build, check, test static, test pipeline, test policy, test asset all pass.
  • Pipeline tests: 3 fixtures / 21 events covering allowed and denied requests, HTTP-status outcome fallback, pods/exec, RBAC objects, core API group normalization, Secret and SecretList redaction, SubjectAccessReview, event.original preservation modes, ARN-style log group metadata, dotted user.extra keys, and malformed field shapes.
  • Policy tests: 8 fixtures covering ARN/name/prefix selector precedence, agentless cloud connector, static credentials, and shared-profile assume-role.
  • Live end-to-end collection verified with Elastic Agent against a real EKS cluster's CloudWatch log group in all three selector modes (ARN, name, prefix) via elastic-package test system.
  • Replayed 309,593 real EKS audit events (7 days) through the installed pipeline: 0 failure-store documents, 0 pipeline errors, 0 unexpected mapped fields, 0 secret leaks.
  • Fuzzed 1,600 polymorphic audit documents (scalars where objects are expected and vice versa, 9,000 unique custom body keys): 0 failure-store documents, 0 new mapped fields.
  • All 44 AWS EKS detection rules (23 KQL, 10 ES|QL, 7 new_terms, 4 EQL) executed through Kibana's detection engine preview against the shipped mapping: 44/44 match their positive controls, 0 errors, 0 unmapped-field warnings.
  • event.original is disabled by default; preserve_original_event retains the unredacted payload and the docs say so.
  • logs:GetLogEvents is not required; the docs list only logs:DescribeLogGroups and logs:FilterLogEvents.
  • Replace the changelog.yml link with this PR's URL after opening.

How to test this PR locally

cd packages/aws
elastic-package check
elastic-package test pipeline --data-streams eks_audit
elastic-package test policy --data-streams eks_audit
elastic-package stack up -d -v
elastic-package install
elastic-package test asset

Optional end-to-end against a real cluster (requires an EKS cluster with control-plane audit logging enabled and read access to its CloudWatch log group):

cat > data_stream/eks_audit/_dev/test/system/test-live-config.yml <<'EOF'
input: aws-cloudwatch
vars:
  access_key_id: "{{AWS_ACCESS_KEY_ID}}"
  secret_access_key: "{{AWS_SECRET_ACCESS_KEY}}"
  session_token: "{{AWS_SESSION_TOKEN}}"
data_stream:
  vars:
    log_group_name: /aws/eks/<cluster-name>/cluster
    region_name: <region>
    start_position: beginning
assert:
  min_count: 1
  fields_present:
    - aws.eks.audit.auditID
    - aws.eks.audit.verb
    - user.name
    - event.outcome
EOF
elastic-package test system --data-streams eks_audit -v
rm data_stream/eks_audit/_dev/test/system/test-live-config.yml

Then in Discover, data view logs-aws.eks_audit-*, confirm aws.eks.audit.verb, aws.eks.audit.objectRef.*, user.name, source.ip, user_agent.original, event.outcome, event.category, event.type, and orchestrator.cluster.name populate, and that aws.eks.audit.requestObject / responseObject are present in _source but only declared sub-fields are searchable.

Related issues

Screenshots

image image image image

Copilot AI lite review requested due to automatic review settings September 3, 2026 11:30
@bryans3c bryans3c added the enhancement New feature or request label Sep 3, 2026
@bryans3c
bryans3c requested review from a team as code owners September 3, 2026 11:30
@bryans3c
bryans3c requested a review from a team as a code owner September 3, 2026 11:30
@bryans3c bryans3c added the Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations] label Sep 3, 2026
@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

Pinging @elastic/security-service-integrations (Team:Security-Service Integrations)

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

⚠️ Package docs validation failed. Please check the workflow run for details.

For support, reach out in the #docs Slack channel.

cc @elastic/integration-docs

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Elastic Docs Style Checker (Vale)

Summary: 8 suggestions found

💡 Suggestions (8): Optional style improvements. Apply when helpful.
File Line Rule Message
packages/aws/data_stream/eks_audit/fields/fields.yml 220 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/aws/data_stream/eks_audit/fields/fields.yml 223 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/aws/data_stream/eks_audit/fields/fields.yml 229 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/aws/data_stream/eks_audit/fields/fields.yml 322 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/aws/data_stream/eks_audit/fields/fields.yml 325 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/aws/data_stream/eks_audit/fields/fields.yml 331 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/aws/data_stream/eks_audit/manifest.yml 64 Elastic.WordChoice Consider using 'can, might' instead of 'may', unless the term is in the UI.
packages/aws/data_stream/eks_audit/manifest.yml 124 Elastic.WordChoice Consider using 'deactivated, deselected, hidden, turned off, unavailable' instead of 'disabled', unless the term is in the UI.

The Vale linter checks documentation changes against the Elastic Docs style guide. To use Vale locally or report issues, refer to Elastic style guide for Vale.

Comment thread packages/aws/changelog.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The current implementation has user-facing inconsistencies (notably preserve_original_event behavior and changelog PR link correctness) that should be resolved before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a new AWS integration data stream (aws.eks_audit) to collect and parse Amazon EKS Kubernetes API audit logs from CloudWatch Logs, including a dedicated Fleet policy template and full ingest pipeline/field mapping/test coverage.

Changes:

  • Register a new Amazon EKS policy template in the AWS package and bump package version/changelog.
  • Add the eks_audit data stream (agent stream template, ingest pipelines, fields, sample event) to parse EKS audit events into aws.eks.audit.* + ECS with redaction/normalization.
  • Add docs and pipeline/policy fixtures to validate configuration precedence and parsing behavior.
File summaries
File Description
packages/aws/manifest.yml Bump package version; register Amazon EKS policy template.
packages/aws/docs/README.md Add EKS row to service/data coverage table.
packages/aws/docs/eks.md New EKS audit stream documentation and field reference.
packages/aws/data_stream/eks_audit/sample_event.json New sample event for the dataset.
packages/aws/data_stream/eks_audit/manifest.yml Define the eks_audit data stream and its vars.
packages/aws/data_stream/eks_audit/fields/fields.yml Define aws.eks.audit.* and related AWS fields.
packages/aws/data_stream/eks_audit/fields/ecs.yml Declare ECS fields used by the data stream.
packages/aws/data_stream/eks_audit/fields/base-fields.yml Define base data stream fields/constants.
packages/aws/data_stream/eks_audit/elasticsearch/ingest_pipeline/default.yml Default pipeline to enrich CloudWatch metadata and route to audit parsing.
packages/aws/data_stream/eks_audit/elasticsearch/ingest_pipeline/audit.yml Core audit JSON parsing, normalization, redaction, ECS projection.
packages/aws/data_stream/eks_audit/agent/stream/aws-cloudwatch.yml.hbs Agent stream template for aws-cloudwatch input selection/vars.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-static-credentials.yml Policy test fixture for static credentials + ARN mode.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-static-credentials.expected Expected rendered policy output for static credentials fixture.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-shared-profile-assume-role.yml Policy test fixture for shared profile + role assume.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-shared-profile-assume-role.expected Expected rendered policy output for shared profile + role assume.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-name-precedence.yml Policy test fixture for name-vs-prefix precedence.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-name-precedence.expected Expected rendered policy output for name precedence fixture.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-default-prefix.yml Policy test fixture for default /aws/eks/ prefix mode.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-default-prefix.expected Expected rendered policy output for default prefix fixture.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-arn-precedence.yml Policy test fixture for ARN precedence over name/prefix.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-arn-precedence.expected Expected rendered policy output for ARN precedence fixture.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-agentless-cloud-connector.yml Policy test fixture for agentless cloud connector mode.
packages/aws/data_stream/eks_audit/_dev/test/policy/test-agentless-cloud-connector.expected Expected rendered policy output for agentless cloud connector fixture.
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit.log-expected.json Pipeline expected outputs for primary fixture set.
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit.log-config.yml Pipeline test config (fields/tags/input metadata).
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit.log Pipeline input events (JSON audit lines).
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit-no-preserve.log-expected.json Pipeline expected outputs for “no preserve” fixture.
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit-no-preserve.log-config.yml Pipeline config for “no preserve” fixture.
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit-no-preserve.log Pipeline input events for “no preserve” fixture.
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit-arn.log-expected.json Pipeline expected outputs for ARN-style log_group metadata fixture.
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit-arn.log-config.yml Pipeline config for ARN-style log_group metadata fixture.
packages/aws/data_stream/eks_audit/_dev/test/pipeline/test-eks-audit-arn.log Pipeline input event for ARN-style log_group metadata fixture.
packages/aws/changelog.yml Add 8.2.0 changelog entry for EKS audit stream.
packages/aws/_dev/build/docs/README.md Generated docs update (service/data coverage table).
packages/aws/_dev/build/docs/eks.md Generated docs page for EKS audit stream.
.github/CODEOWNERS Add ownership for the new eks_audit data stream.
Review details
  • Files reviewed: 33/36 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +21 to +27
- rename:
tag: rename_message_to_event_original
field: message
if: ctx.event?.original == null
ignore_missing: true
target_field: event.original
- json:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is handled centrally by Fleet, not per-integration. Verified end-to-end against a live logs-aws.eks_audit-* data stream: a document without the tag is indexed without event.original and the same document with the tag retains it. Pipeline test fixtures show event.original only because elastic-package test pipeline simulates the package pipeline in isolation.

Comment thread packages/aws/changelog.yml Outdated
Copilot AI review requested due to automatic review settings September 3, 2026 14:19
@elastic-vault-github-plugin-prod

Copy link
Copy Markdown
Contributor

✅ All changelog entries have the correct PR link.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The ingest pipeline currently retains event.original even when “Preserve original event” is disabled, which contradicts the documented behavior and increases sensitive-data retention risk.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

packages/aws/docs/eks.md:31

  • Grammar: “looks as following” should be “looks as follows”.

packages/aws/data_stream/eks_audit/elasticsearch/ingest_pipeline/audit.yml:25

  • preserve_original_event is documented as controlling whether event.original is populated, but this pipeline always renames message to event.original unconditionally (whenever event.original is absent). As a result, raw audit payloads can be retained even when users leave Preserve original event disabled, which undermines the intent to minimize sensitive-data retention (notably for Secret events) and contradicts the stream var description.
- rename:
    tag: rename_message_to_event_original
    field: message
    if: ctx.event?.original == null
    ignore_missing: true
  • Files reviewed: 33/36 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@vera-review-bot

Copy link
Copy Markdown

🟢 No issues across the latest commits 1b65e59.

Review summary

Issues found across earlier commits 0d64e2f — 1 medium
  • 🟡 Changelog links a different PR number (link) (Resolved)

A new commit triggers another review — at most once every 15 minutes. I skip the PR while it's approved or has merge conflicts.

🤖 AI-Generated Review | Vera Review Bot - v0.3.0 | 📚 Knowledge base: integration-skills

⚠️ Automated review — verify suggestions before applying.

@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

💚 Build Succeeded

History

@vera-review-bot

Copy link
Copy Markdown

@bryans3c - This PR has merge conflicts with the base branch. Please resolve them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Integration:aws AWS Team:Security-Service Integrations Security Service Integrations team [elastic/security-service-integrations]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants