Loading

How Container Workload Protection Works

<div class="condensed-table">
| | |
| --- | --- |
| Version | 1.2.7 (View all) |
| Compatible Kibana version(s) | 8.11.0 or higher |
| Supported Serverless project types
What’s this? | Security |
| Subscription level
What’s this? | Enterprise |
| Level of support
What’s this? | Elastic |

</div>
CWP is powered by a lightweight integration (Defend for Containers BETA) that is bundled and configured by the Elastic Agent. The agent is installed as a daemonset on supported Kubernetes clusters and the integration uses eBPF LSM and tracepoint probes to produce system events. Events are evaluated against eBPF LSM hook points, enabling a configured policy to be evaluated before system activity is allowed to proceed.

The policy determines which system behaviors (for example, process executions, file creations or deletions, etc) will result in an action. Actions are simple: logging the behavior to Elasticsearch, creating an alert in Elasticsearch, or blocking the behavior.

The system ships with a default policy configured featuring two selectors and responses. The first selector is designed to stream process telemetry events to the user’s Elasticsearch cluster. The policy uses the selector allProcesses which specifies fork and exec operations. This selector is mapped to the allProcesses response, which specifies a log action.

The resulting telemetry data is transformed into an ECS document and streamed back to the user’s Elasticsearch cluster, where the Elastic Security SIEM evaluates the data to detect malicious behavior.

The second selector is written to detect the modification of existing executables or the creation of new executables within a container (This is how Elastic detects “container drift”). The policy selector is named executableChanges and is mapped to a response section called executableChanges which specifies an alert action.

This policy is configured with an alert response, meaning that when drift conditions are detected, the matching event(s) are collected and written as an alert to the user’s Elasticsearch cluster. A prebuilt rule “escalation rule” in the SIEM watches for these alert documents and raises an alert in the SIEM when drift is detected. This policy can also be modified to block drift operations by changing the response action to block.

Users that want to use the full strength of CWP will benefit to understand the system’s policy syntax, which enables fine-grained policies to be constructed. Policies can be built to precisely match expected container behaviors– disallowing any unexpected behaviors– and thereby substantially hardening the security posture of container workloads.

Policies are composed of selectors and responses. A given policy must contain at least one selector and one response. Currently, the system supports two types of selectors and responses, file and process. Selectors tell the service what system operations to match and have a number of conditions that can be grouped together (using a logical AND operation) to provide precise control. Responses instruct the system on what actions to take when system operations match selectors.

The service can be deployed in two ways: declaratively using Elastic Agent in standalone mode, or as a managed D4C integration through Fleet. With the former, teams have the flexibility to integrate their policies into Git for an infrastructure-as-code (IoC) approach, streamlining the deployment process and enabling easier management.

Note

You will need to include the following capabilities under securityContext in your k8s yaml in order for the service to work.

securityContext:
    runAsUser: 0
    # The following capabilities are needed for 'Defend for containers' integration (cloud-defend)
    # If you are using this integration, please uncomment these lines before applying.
    capabilities:
      add:
        - BPF1
        - PERFMON2
        - SYS_RESOURCE3
  1. (since Linux 5.8) allows loading of BPF programs, create most map types, load BTF, iterate programs and maps.
  2. (since Linux 5.8) allows attaching of BPF programs used for performance metrics and observability operations.
  3. Allow use of special resources or raising of resource limits. Used by 'Defend for Containers' to modify 'rlimit_memlock'

A given policy must contain at least one selector (file or process) and one response.

process:
  selectors:
    - name: allProcesses
      operation: [fork, exec]
    - name: interactiveProcesses
      operation: [fork, exec]
      sessionLeaderInteractive: true
  responses:
    - match: [allProcesses]
      actions: [log]
    - match: [interactiveProcesses]
      actions: [alert]
file:
  selectors:
    - name: executableChanges
      operation: [createExecutable, modifyExecutable]
  responses:
    - match: [executableChanges]
      actions: [alert]

[TBC: QUOTE]

A selector tells the service what system operations to match on and has a number of conditions that can be grouped together (using a logical AND operation) to provide precise control.

- name: exampleFileSelector
  operation: [createExecutable, modifyExecutable]
  containerImageName: [nginx]
  containerImageTag: [latest]
  targetFilePath: [/usr/bin/**]
  kubernetesClusterId: [cluster1]
  kubernetesClusterName: [stagingCluster]
  kubernetesNamespace: [default]
  kubernetesPodLabel: [‘production:*’]
  kubernetesPodName: [‘nginx-pod-*’]
  ignoreVolumeMounts: true

A selector MUST contain a name and at least one of the following conditions.

Name Description
containerImageFullName A list of container full image names to match on. e.g. "docker.io/nginx".
containerImageName A list of container image names to match on. e.g. nginx
containerImageTag A list of container image tags to match on. e.g. latest
kubernetesClusterId A list of kubernetes cluster IDs to match on. For consistency with KSPM, the kube-system namespace uid is used as a cluster ID.
kubernetesClusterName A list of kubernetes cluster names to match on.
kubernetesNamespace A list of kubernetes namespaces to match on.
kubernetesPodName A list of kubernetes pod names to match on. Trailing wildcards supported.
kubernetesPodLabel A list of resource labels. Trailing wildcards supported (value only). e.g. key1:val*

[TBC: QUOTE]

- name:
  operation: [createExecutable]
  kubernetesPodLabel: [environment:production, service:auth*]
Name Description
operation The list of system operations to match on. Options include createExecutable, modifyExecutable, createFile, modifyFile, deleteFile.
ignoreVolumeMounts If set, ignores file operations on ALL volume mounts.
ignoreVolumeFiles If set, ignores operations on file mounts only. e.g. mounted files, configMaps, secrets etc…​
targetFilePath A list of file paths to include. Paths are absolute and wildcards are supported.

[TBC: QUOTE]

- name:
  targetFilePath: [/usr/bin/echo, /usr/sbin/*, /usr/local/**]

In this example,

  • /usr/bin/echo will match on the echo binary, and only this binary
  • /usr/local/** will match on everything recursively under /usr/local/ including /usr/local/bin/something
  • /usr/sbin/* includes everything that’s a direct child of /usr/sbin
Name Description
operation The list of system operations to match on. Options include fork and exec.
processExecutable A list of executables (full path included) to match on. e.g. /usr/bin/cat. Wildcard support is same as targetFilePath above.
processName A list of process names (executable basename) to match on. e.g. bash, vi, cat etc…​
sessionLeaderInteractive If set to true, will only match on interactive sessions (i.e. sessions with a controlling TTY)

Responses instruct the system on what actions to take when system operations match selectors.

A policy can contain one or more responses. Each response is comprised of the following:

responses:
  - match: [allProcesses]
    exclude: [excludeSystemDServices]
    actions: [log]
  - match: [nefariousActivity]
    actions: [alert, block]
Response Field Description
match An array of one or more selectors of the same type (file or process).
exclude An optional array of one or more selectors to use as exclusions to everything in match
actions An array of actions to perform (if at least one match and none of the exclude selectors match). Options include log, alert and block.

Action Description
log Sends events to the logs-cloud_defend.file-* data stream for file responses, and the logs-cloud_defend.process-* data stream for process responses.
alert Writes events (file or process) to the logs-cloud_defend.alerts-* data stream.
block Prevents the system operation from proceeding. This blocking action happens prior to the execution of the event. It is required that the alert action be set if block is enabled.

Consider the following yaml.

file:
  selectors:
    - name: binDirExeMods
      operation:
        - createExecutable
        - modifyExecutable
      targetFilePath:
        - /usr/bin/**
    - name: etcFileChanges
      operation:
        - createFile
        - modifyFile
        - deleteFile
      targetFilePath:
        - /etc/**
    - name: nginx
      containerImageName:
        - nginx

  responses:
    - match:
        - binDirExeMods
        - etcFileChanges
      exclude:
        - nginx
      actions:
        - alert
        - block

We have three file selectors. Two are used to match (logically OR’d), and one to exclude.

This could be read as: If an executable is created or modified under /usr/bin or a file is created, modified or deleted under /etc, block and create an alert as long as it’s not an nginx container.

e.g.

IF (binDirExeMods OR etcFileChanges) AND NOT nginx = RUN ACTIONS alert and block

The following fields are populated for all events where event.category: process

Field Examples
@timestamp 2023-03-20T16:03:59.520Z
agent.id 7829f26d-c2d1-4eaf-a1ac-cd9cb9e12f75
agent.type cloud-defend
agent.version 8.8.0
cloud.account.id 1234567abc
cloud.account.name elastic-dev
cloud.availability_zone us-east-1c
cloud.instance.name webapp-node
cloud.project.id 123456abc
cloud.project.name staging
cloud.provider aws
cloud.region us-east-1
cloud_defend.matched_selectors [interactiveSessions]
cloud_defend.package_policy_id 4c9cbba0-c812-11ed-a8dd-91ec403e4f03
cloud_defend.package_policy_revision 2
cloud_defend.hook_point [tracepointsched_process_fork*,tracepointsched_process_exec*, kprobe__taskstats_exit]
container.id nginx_1
container.image.name nginx
container.image.tag latest
data_stream.dataset cloud_defend.process
data_stream.namespace default
data_stream.type logs
ecs.version 8.7.0
event.action fork, exec, end
event.agent_id_status verified
event.category process
event.created 2023-03-20T16:03:59.520Z
event.dataset cloud_defend.process
event.id 3ee85eee-72d9-4e9d-934f-3787952ca830
event.ingested 2023-03-20T16:04:12Z
event.kind event, alert
event.module cloud_defend
event.type start, end, denied
group.id 0
host.architecture amd64
host.boot.id 815a760f-8153-49e1-9d0b-da0d3b2a468c
host.id 1bb9e6a948dfb1c3cd38d1fdc8de4481
host.ip [127.0.0.1, 172.20.0.2, 172.18.0.6]
host.hostname kibana-node
host.mac [32:a9:cc:26:4c:e5, 7a:ec:f0:3e:29:ee]
host.name kibana-node.myapp.co
host.os.family ubuntu
host.os.full Ubuntu 20.04.5
host.os.kernel 5.10.161+ #1 SMP Thu Jan 5 22:49:42 UTC 2023
host.os.name 'Linux
host.os.platform ubuntu
host.os.type linux
host.os.version 20.04.5
host.pid_ns_ino 4026531836
orchestrator.cluster.id 12345
orchestrator.cluster.name website
orchestrator.namespace default
orchestrator.resource.ip 172.18.0.6
orchestrator.resource.annotation [note:testing]
orchestrator.resource.label [service:webapp]
orchestrator.resource.name webapp-proxy
orchestrator.resource.parent.type DaemonSet, ReplicaSet etc…​
orchestrator.resource.type pod
process.args [ls, --color=auto]
process.end 2023-03-20T16:04:12Z
process.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.entry_leader.args [bash]
process.entry_leader.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.entry_leader.entry_meta.type container
process.entry_leader.executable /bin/bash
process.entry_leader.group.id 0
process.entry_leader.interactive true
process.entry_leader.name bash
process.entry_leader.pid 1915529
process.entry_leader.same_as_process false
process.entry_leader.start 2023-03-20T16:03:59.520Z
process.entry_leader.user.id 0
process.entry_leader.working_directory /usr/share/elastic-agent
process.executable /usr/bin/ls
process.group_leader.args [ls, --color=auto]
process.group_leader.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.group_leader.executable /usr/bin/ls
process.group_leader.group.id 0
process.group_leader.interactive true
process.group_leader.name ls
process.group_leader.pid 1915529
process.group_leader.same_as_process true
process.group_leader.start 2023-03-20T16:03:59.520Z
process.group_leader.user.id 0
process.group_leader.working_directory /usr/share/elastic-agent
process.interactive true
process.name ls
process.parent.args [bash]
process.parent.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.parent.executable /bin/bash
process.parent.group.id 0
process.parent.interactive true
process.parent.name bash
process.parent.pid 1915529
process.parent.same_as_process false
process.parent.start 2023-03-20T16:03:59.520Z
process.parent.user.id 0
process.parent.working_directory /usr/share/elastic-agent
process.pid 1916234
process.previous [{ args: [bash], executable: /bin/bash}]
process.previous.args [bash]
process.previous.executable /bin/bash
process.session_leader.args [bash]
process.session_leader.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.session_leader.executable /bin/bash
process.session_leader.group.id 0
process.session_leader.interactive true
process.session_leader.name bash
process.session_leader.pid 1915529
process.session_leader.same_as_process false
process.session_leader.start 2023-03-20T16:03:59.520Z
process.session_leader.user.id 0
process.session_leader.working_directory /usr/share/elastic-agent
process.start 2023-03-20T16:03:59.520Z
process.working_directory /usr/share/elastic-agent
user.id 0

The following fields are populated for all events where event.category: file

Field Examples
@timestamp 2023-03-20T16:03:59.520Z
agent.id 7829f26d-c2d1-4eaf-a1ac-cd9cb9e12f75
agent.type cloud-defend
agent.version 8.8.0
cloud.account.id 1234567abc
cloud.account.name elastic-dev
cloud.availability_zone us-east-1c
cloud.project.id 123456abc
cloud.project.name staging
cloud.provider aws
cloud.region us-east-1
cloud_defend.matched_selectors [binModifications]
cloud_defend.package_policy_id 4c9cbba0-c812-11ed-a8dd-91ec403e4f03
cloud_defend.package_policy_revision 2
cloud_defend.hook_point One of: lsmpath_chmod, lsmpath_mknod, lsmfile_open, lsmpath_truncate, lsmpath_rename, lsmpath_link, lsm__path_unlink
container.id nginx_1
container.image.name nginx
container.image.tag latest
data_stream.dataset cloud_defend.process
data_stream.namespace default
data_stream.type logs
ecs.version 8.7.0
event.action One of: creation, modification, deletion, rename, link, open
event.agent_id_status verified
event.category process
event.created 2023-03-20T16:03:59.520Z
event.dataset cloud_defend.process
event.id 3ee85eee-72d9-4e9d-934f-3787952ca830
event.ingested 2023-03-20T16:04:12Z
event.kind One of: event, alert
event.module cloud_defend
event.type One of: start, end, denied
file.extension ts
file.name script.ts
file.path /home/workspace/project/script.ts
group.id 0
host.architecture amd64
host.boot.id 815a760f-8153-49e1-9d0b-da0d3b2a468c
host.id 1bb9e6a948dfb1c3cd38d1fdc8de4481
host.ip [127.0.0.1, 172.20.0.2, 172.18.0.6]
host.hostname kibana-node
host.mac [32:a9:cc:26:4c:e5, 7a:ec:f0:3e:29:ee]
host.name kibana-node.myapp.co
host.os.family ubuntu
host.os.full Ubuntu 20.04.5
host.os.kernel 5.10.161+ #1 SMP Thu Jan 5 22:49:42 UTC 2023
host.os.name 'Linux
host.os.platform ubuntu
host.os.type linux
host.os.version 20.04.5
host.pid_ns_ino 4026531836
orchestrator.cluster.id 12345
orchestrator.cluster.name website
orchestrator.namespace default
orchestrator.resource.ip 172.18.0.6
orchestrator.resource.annotation [note:testing]
orchestrator.resource.label [service:webapp]
orchestrator.resource.name webapp-proxy
orchestrator.resource.parent.type …​
orchestrator.resource.type pod
process.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.entry_leader.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.executable /usr/bin/vi
process.group_leader.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.interactive true
process.name vi
process.parent.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.pid 1916234
process.session_leader.entity_id NzgyOWYyNmQtYzJkMS00ZWFmLWExYWMtY2Q5Y2I5ZTEyZjc1LTE5MTU1MzUtMTY3OTMyODIzOQ==
process.user.id 0
user.id 0
EKS 1.24-1.27 (AL2022) GKE 1.24-1.27 (COS)
Process event exports
File event exports
Drift prevention
Mount point awareness
Process blocking
Network event exports Coming soon Coming soon
Network blocking Coming soon Coming soon