Events
Tetragon’s events are exposed to the system through either the gRPC endpoint or JSON logs. Commands in this section assume the Getting Started guide was used, but are general other than the namespaces chosen and should work in most environments.
JSON
The first way is to observe the raw json output from the stdout container log:
kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon -c export-stdout -f
The raw JSON events provide Kubernetes API, identity metadata, and OS
level process visibility about the executed binary, its parent and the execution
time. A base Tetragon installation will produce process_exec
and process_exit
events encoded in JSON as shown here,
Process execution event
{
"process_exec": {
"process": {
"exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4Njc0MzIxMzczOjUyNjk5",
"pid": 52699,
"uid": 0,
"cwd": "/",
"binary": "/usr/bin/curl",
"arguments": "https://ebpf.io/applications/#tetragon",
"flags": "execve rootcwd",
"start_time": "2023-10-06T22:03:57.700327580Z",
"auid": 4294967295,
"pod": {
"namespace": "default",
"name": "xwing",
"container": {
"id": "containerd://551e161c47d8ff0eb665438a7bcd5b4e3ef5a297282b40a92b7c77d6bd168eb3",
"name": "spaceship",
"image": {
"id": "docker.io/tgraf/netperf@sha256:8e86f744bfea165fd4ce68caa05abc96500f40130b857773186401926af7e9e6",
"name": "docker.io/tgraf/netperf:latest"
},
"start_time": "2023-10-06T21:52:41Z",
"pid": 49
},
"pod_labels": {
"app.kubernetes.io/name": "xwing",
"class": "xwing",
"org": "alliance"
},
"workload": "xwing"
},
"docker": "551e161c47d8ff0eb665438a7bcd5b4",
"parent_exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4NjcwODgzMjk5OjUyNjk5",
"tid": 52699
},
"parent": {
"exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4NjcwODgzMjk5OjUyNjk5",
"pid": 52699,
"uid": 0,
"cwd": "/",
"binary": "/bin/bash",
"arguments": "-c \"curl https://ebpf.io/applications/#tetragon\"",
"flags": "execve rootcwd clone",
"start_time": "2023-10-06T22:03:57.696889812Z",
"auid": 4294967295,
"pod": {
"namespace": "default",
"name": "xwing",
"container": {
"id": "containerd://551e161c47d8ff0eb665438a7bcd5b4e3ef5a297282b40a92b7c77d6bd168eb3",
"name": "spaceship",
"image": {
"id": "docker.io/tgraf/netperf@sha256:8e86f744bfea165fd4ce68caa05abc96500f40130b857773186401926af7e9e6",
"name": "docker.io/tgraf/netperf:latest"
},
"start_time": "2023-10-06T21:52:41Z",
"pid": 49
},
"pod_labels": {
"app.kubernetes.io/name": "xwing",
"class": "xwing",
"org": "alliance"
},
"workload": "xwing"
},
"docker": "551e161c47d8ff0eb665438a7bcd5b4",
"parent_exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4NjQ1MjQ1ODM5OjUyNjg5",
"tid": 52699
}
},
"node_name": "gke-john-632-default-pool-7041cac0-9s95",
"time": "2023-10-06T22:03:57.700326678Z"
}
Will only highlight a few important fields here. For a full specification of events see the Reference
section. All events in Tetragon contain a process_exec
block to identify the process generating the
event. For execution events this is the primary block. For Tracing Policy events the
hook that generated the event will attach further data to this. The process_exec
event provides
a cluster wide unique id the process_exec.exec_id
for this process along with the metadata expected
in a Kubernetes cluster process_exec.process.pod
. The binary and args being executed are part of
the event here process_exec.process.binary
and process_exec.process.args
. Finally, a node_name
and time
provide the location and time for the event and will be present in all event types.
A default deployment writes the JSON log to /var/run/cilium/tetragon/tetragon.log
where it can
be exported through normal log collection tooling, e.g. ‘fluentd’, logstash, etc.. The file will
be rotated and compressed by default. See [Helm Options] for details on how to customize this location.
Export Filtering
Export filters restrict the JSON event output to a subset of desirable events. These export filters are configured as a line-separated list of JSON objects, where each object can contain one or more filter expressions. Filters are combined by taking the logical OR of each line-separated filter object and the logical AND of sibling expressions within a filter object. As a concrete example, suppose we had the following filter configuration:
{"event_set": ["PROCESS_EXEC", "PROCESS_EXIT"], "namespace": "foo"}
{"event_set": ["PROCESS_KPROBE"]}
The above filter configuration would result in a match if:
- The event type is
PROCESS_EXEC
orPROCESS_EXIT
AND the pod namespace is “foo”; OR - The event type is
PROCESS_KPROBE
Tetragon supports two groups of export filters: an allowlist and a denylist. If neither is configured, all events are exported. If only an allowlist is configured, event exports are considered default-deny, meaning only the events in the allowlist are exported. The denylist takes precedence over the allowlist in cases where two filter configurations match on the same event.
You can configure export filters using the provided helm options, command line flags, or environment variables.
List of Process Event Filters
Filter | Description |
---|---|
event_set | Filter process events by event types. Supported types include: PROCESS_EXEC , PROCESS_EXIT , PROCESS_KPROBE , PROCESS_UPROBE , PROCESS_TRACAEPOINT , PROCESS_LOADER |
binary_regex | Filter process events by a list of regular expressions of process binary names (e.g. "^/home/kubernetes/bin/kubelet$" ). You can find the full syntax here. |
health_check | Filter process events if their binary names match Kubernetes liveness / readiness probe commands of their corresponding pods. |
namespace | Filter by Kubernetes pod namespaces. An empty string ("" ) filters processes that do not belong to any pod namespace. |
pid | Filter by process PID. |
pid_set | Like pid but also includes processes that are descendants of the listed PIDs. |
pod_regex | Filter by pod name using a list of regular expressions. You can find the full syntax here. |
arguments_regex | Filter by process arguments using a list of regular expressions. You can find the full syntax here. |
labels | Filter events by pod labels using Kubernetes label selector syntax Note that this filter never matches events without the pod field (i.e. host process events). |
policy_names | Filter events by tracing policy names. |
capabilities | Filter events by Linux process capability. |
cel_expression | Filter using CEL expressions. CEL filters support IP and CIDR notiation extensions from the k8s project. See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#IP and https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#CIDR for details. |
parent_binary_regex | Filter process events by a list of regular expressions of parent process binary names (e.g. "^/home/kubernetes/bin/kubelet$" ). You can find the full syntax here. |
parent_arguments_regex | Filter by the container ID in the process.docker field using RE2 regular expression syntax: https://github.com/google/re2/wiki/Syntax |
container_id | Filter by parent process arguments using a list of regular expressions. You can find the full syntax here. |
in_init_tree | Filter containerized processes based on whether they are descendants of the container’s init process. This can be used, for example, to watch for processes injected into a container via docker exec, kubectl exec, or similar mechanisms. |
Field Filtering
In some cases, it is not desirable to include all of the fields exported in Tetragon events by default. In these cases, you can use field filters to restrict the set of exported fields for a given event type. Field filters are configured similarly to export filters, as line-separated lists of JSON objects.
Field filters select fields using the protobuf field mask syntax
under the "fields"
key. You can define a path of fields using field
names separated by period (.
) characters. To define multiple paths in
a single field filter, separate them with comma (,
) characters. For
example, "fields":"process.binary,parent.binary,pod.name"
would select
only the process.binary
, parent.binary
, and pod.name
fields.
By default, a field filter applies to all process events, although you
can control this behaviour with the "event_set"
key. For example, you
can apply a field filter to PROCESS_CONNECT
and PROCESS_CLOSE
events
by specifying "event_set":["PROCESS_CONNECT","PROCESS_CLOSE"]
in the
filter definition.
Each field filter has an "action"
that determines what the filter
should do with the selected field. The supported action types are
"INCLUDE"
and "EXCLUDE"
. A value of "INCLUDE"
will cause the field
to appear in an event, while a value of "EXCLUDE"
will hide the field.
In the absence of any field filter for a given event type, the export
will include all fields by default. Defining one or more "INCLUDE"
filters for a given event type changes that behaviour to exclude all
other event types by default.
As a simple example of the above, consider the case where we want to include
only exec_id
and parent_exec_id
in all event types except for
PROCESS_EXEC
:
{"fields":"process.exec_id,process.parent_exec_id", "event_set": ["PROCESS_EXEC"], "invert_event_set": true, "action": "INCLUDE"}
Redacting Sensitive Information
Since Tetragon traces the entire system, event exports might sometimes contain
sensitive information (for example, a secret passed via a command line argument
to a process). To prevent this information from being exfiltrated via Tetragon
JSON export, Tetragon provides a mechanism called Redaction Filters which can be
used to string patterns to redact from exported process arguments. These filters are written
in JSON and passed to the Tetragon agent via the --redaction-filters
command
line flag or the redactionFilters
Helm value.
To perform redactions, redaction filters define RE2 regular expressions in the
redact
field. Any capture groups in these RE2 regular expressions are redacted and
replaced with "*****"
.
\Wpasswd\W?
would be written as {"redact": "\\Wpasswd\\W?"}
.For more control, you can select which binary or binaries should have their
arguments redacted with the binary_regex
field.
As a concrete example, the following will redact all passwords passed to
processes with the "--password"
argument:
{"redact": ["--password(?:\\s+|=)(\\S*)"]}
Now, an event that contains the string "--password=foo"
would have that string
replaced with "--password=*****"
.
Suppose we also see some passwords passed via the -p shorthand for a specific binary, foo. We can also redact these as follows:
{"binary_regex": ["(?:^|/)foo$"], "redact": ["-p(?:\\s+|=)(\\S*)"]}
With both of the above redaction filters in place, we are now redacting all password arguments.
tetra
CLI
A second way is to use the tetra
CLI. This
has the advantage that it can also be used to filter and pretty print the output. The tool
allows filtering by process, pod, and other fields. To install tetra see the
Tetra Installation Guide
To start printing events run:
kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon -c export-stdout -f | tetra getevents -o compact
The tetra
CLI is also available inside tetragon
container.
kubectl exec -it -n kube-system ds/tetragon -c tetragon -- tetra getevents -o compact
This was used in the quick start and generates a pretty printing of the events, To further filter by a specific binary and/or pod do the following,
kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon -c export-stdout -f | tetra getevents -o compact --processes curl --pod xwing
Will filter and report just the relevant events.
🚀 process default/xwing /usr/bin/curl https://ebpf.io/applications/#tetragon
💥 exit default/xwing /usr/bin/curl https://ebpf.io/applications/#tetragon 60
gRPC
In addition Tetragon can expose a gRPC endpoint listeners may attach to. The
gRPC is exposed by default helm install on localhost:54321
, but the address
can be configured with the --server-address
option. This can be
set from helm with the tetragon.grpc.address
flag or disabled completely if
needed with tetragon.grpc.enabled
.
helm install tetragon cilium/tetragon -n kube-system --set tetragon.grpc.enabled=true --set tetragon.grpc.address=localhost:54321
An example gRPC endpoint is the Tetra CLI when its not piped JSON output directly,
kubectl exec -ti -n kube-system ds/tetragon -c tetragon -- tetra getevents -o compact