Self-hosted service
aquasecurity/tracee avatar
aquasecurity/tracee

Aqua Tracee: eBPF runtime security and forensics for Linux

Linux Runtime Security and Forensics using eBPF

4,625 stars509 forksGoApache-2.0

At a glance

What is it?
Tracee observes Linux system and application behaviour through eBPF and turns it into events and behavioural detections. It runs as a privileged container or a Kubernetes DaemonSet, and the documentation is the only place the install paths are spelled out.
Who is it for?
Adopt Tracee if you need kernel-level visibility on Linux hosts or Kubernetes nodes and you can grant a privileged container or DaemonSet the access eBPF requires. Skip it if your fleet is mostly macOS or Windows, or if you cannot run privileged workloads.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Tracee solves, and who ends up running it

Most host security tooling sits above the kernel: it reads logs, watches files, or polls process tables. Tracee takes the opposite position. According to the README, it is "a runtime security and observability tool" that uses eBPF "to tap into your system and expose that information as events that you can consume." Those events are split into two kinds: factual system activity, and what the README calls "sophisticated security events that detect suspicious behavioral patterns."

The distinction matters. Factual events tell you a process executed or a file was opened. The behavioural detections are the part that requires judgement, because they describe patterns rather than single actions.

The audience is narrow and specific. Tracee is written in Go and targets Linux, with Kubernetes as a first-class deployment target, which the repository topics confirm (bpf, docker, ebpf, golang, kubernetes, linux, runtime-security, security). If your estate is Linux servers or Kubernetes nodes and you want visibility into what processes do after they start, this is aimed at you. If you are securing developer laptops that are mostly macOS, the README points Mac users to a separate FAQ page rather than to a supported install path, which tells you where the project's centre of gravity is.

How eBPF events become detections

The mechanism is eBPF programs attached to kernel hooks. The Go binary loads them and reads what they emit. The repository layout reflects that split: cmd/ holds the entry points, pkg/ holds the Go packages, and the Makefile builds a target list of "signatures tracee evt traceectl lsm-check", with an eBPF build tag set of "core,ebpf,lsmsupport". The presence of lsm-check and the lsmsupport tag indicates the project also uses Linux Security Module hooks, not only tracepoints.

A detail in the Makefile is worth pausing on. It exports GOEXPERIMENT with the value norandomizedheapbase64, and the comment explains why: Go 1.26 randomizes the heap base address, which "breaks the eBPF stack_pivot detector's Go heap recognition" because the eBPF code expects arenas starting at 0xc000000000. That is an honest trade-off recorded in the build system. A security tool that turns off a memory-randomization experiment to keep a detector working is telling you something about how tightly the detection logic is bound to Go runtime internals. It is not a flaw, but it is a coupling that will need revisiting when the eBPF side is updated.

On the output side, go.mod pulls in gRPC and protobuf alongside a prometheus client and a Fluent Forward client, so events can leave the process over more than one channel. The examples/ directory ships config, detectors and policies samples, which is where the policy format is actually demonstrated.

Running the Docker quickstart

The README gives a single docker run command as the fastest way to try Tracee. It needs host PID and cgroup namespaces plus privileged mode, and it mounts two host paths read-only so the container can identify the host and reach its runtime socket. The os-release mount is renamed to /etc/os-release-host inside the container, which is how Tracee distinguishes host identity from container identity.

bash
docker run --name tracee -it --rm \
  --pid=host --cgroupns=host --privileged \
  -v /etc/os-release:/etc/os-release-host:ro \
  -v /var/run:/var/run:ro \
  aquasec/tracee:latest

Because the container runs attached with -it and --rm, you should see a stream of events in your terminal and the container should disappear when you exit. If nothing appears, the first thing to check is kernel compatibility rather than the command itself: the README states that Tracee "should run on most common Linux distributions and kernels" and points to a Prerequisites page for the compatibility matrix. The README does not document a rollback or cleanup step, but --rm covers the container case.

For a fuller walkthrough the README links a Docker getting started guide, and it also notes that Mac users should read a separate FAQ before trying this, since the privileged Linux container assumptions do not translate.

Installing on Kubernetes with Helm

The Kubernetes path is two commands to install and one to watch output. The chart comes from Aqua's Helm repository and is deployed into its own namespace.

bash
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm repo update
helm install tracee aqua/tracee --namespace tracee --create-namespace

After install, the README shows how to follow the DaemonSet's logs. Note the resource type in the command: it is daemonset/tracee, not deployment/tracee, which matches the fact that host-level eBPF visibility has to run once per node.

bash
kubectl logs --follow --namespace tracee daemonset/tracee

A DaemonSet on every node means every node gets a privileged pod with host PID access. That is the cost of the design, and it is worth stating plainly: you are not installing a passive agent. The README points to a Kubernetes getting started guide for the complete walkthrough, and the chart's own values are not reproduced in the README, so sizing and policy configuration have to come from the documentation site.

Where Tracee is the wrong tool

The privileged requirement is the first real limitation. Both documented install paths demand it: --privileged plus --pid=host in Docker, and a DaemonSet on Kubernetes. On clusters where pod security standards forbid privileged workloads, or where nodes are managed by a platform team that will not grant host PID access, Tracee cannot be installed at all without changing those policies. That is a policy decision, not a configuration flag.

Kernel compatibility is the second. The README says Tracee "should run on most common Linux distributions and kernels" and defers the detail to a Prerequisites page. That phrasing is doing real work: eBPF features vary by kernel version, so "most" is not "all", and the README does not enumerate the exceptions. Anyone planning a fleet-wide rollout has to read that page before committing.

The third case is non-Linux. There is no documented macOS or Windows install path in the README; Mac users are directed to an FAQ instead. If your endpoints are laptops, this is the wrong layer.

Finally, there is a scope question. Tracee reports events and behavioural patterns. The README describes consuming events, not responding to them. If what you actually need is enforcement or automatic remediation, event generation is only the input to that, and you will need something else to act on it.

How Tracee differs from Falco

Falco is the obvious comparison, and the difference is in how detection rules are expressed and where the project invests. Falco's detection logic is written in its own rule language and shipped as rule files you edit and reload. Tracee's repository carries a signatures/ directory and an examples/detectors/ directory, with detectors appearing as a separate Go module in go.mod (github.com/aquasecurity/tracee/detectors). That points to detectors being code artifacts in the Go build rather than rules you rewrite at runtime.

The second difference is the event surface. Tracee's README draws a line between factual system events and behavioural security events, and the Makefile's lsm-check target suggests LSM hooks are part of how it observes. The build also carries an eBPF stack_pivot detector whose Go heap recognition depends on arena layout, which is a level of runtime-specific detection that a pure rule engine would struggle to express.

Neither approach is strictly better. Rule files are easier for a security team to tune without a Go toolchain. Compiled detectors are easier to test and version alongside the engine. Which one you want depends on whether your detection authors write Go or YAML.

Licence, build inputs and what upgrading costs

Tracee is Apache-2.0, and the repository carries both a LICENSE and a NOTICE file. Apache-2.0 is permissive, but the NOTICE file exists for a reason: if you redistribute Tracee or a derivative, read NOTICE and the licence text rather than assuming the permissive grant covers every bundled component. This is not legal advice, and the 3rdparty/ directory plus the libbpf dependency (github.com/aquasecurity/libbpfgo, pinned to a libbpf 1.8 development revision) is exactly the kind of place where a legal review is warranted.

Upgrade cost is dominated by the build toolchain, not the Go code. The Makefile requires a long list of external tools including clang, llc, llvm-strip, llvm-objcopy, protoc, controller-gen, pkg-config and zig, and it fails with "missing required tool" when one is absent. Building from source therefore means provisioning a C and eBPF toolchain, not just a Go compiler. The go.mod targets a recent Go release with an explicit toolchain line, so the Go version is pinned too.

Release cadence gives a rough sense of churn: v0.24.0 and v0.24.1 landed in November 2025, after v0.23.2 in July 2025. The last push to the repository was on 2026-09-15. Anyone pinning a version should expect to re-test detections across minor releases, because detector behaviour is tied to runtime internals as the GOEXPERIMENT comment shows.

Editorial conclusion

Adopt Tracee if you need kernel-level visibility on Linux hosts or Kubernetes nodes and you can grant a privileged container or DaemonSet the access eBPF requires. Skip it if your fleet is mostly macOS or Windows, or if you cannot run privileged workloads. Before rolling it out, read the Prerequisites page for the supported kernel range, then run the Docker quickstart on one host and confirm that events actually appear before you install the Helm chart cluster-wide.

Frequently asked questions

How do I use Tracee on Linux?

The README's quickstart runs Tracee as a privileged Docker container with host PID and cgroup namespaces, mounting /etc/os-release and /var/run read-only from the host. For a complete walkthrough it links a Docker getting started guide.

How do I set up Tracee on Kubernetes?

Add the aqua Helm repository, then install the chart with helm install tracee aqua/tracee --namespace tracee --create-namespace. The README then suggests following the DaemonSet logs with kubectl logs --follow --namespace tracee daemonset/tracee.

What is Tracee from Aqua Security?

It is a runtime security and observability tool that uses eBPF to expose system activity as events, ranging from factual system activity to security events that detect suspicious behavioural patterns. It is an Aqua Security open source project written in Go.

Does Tracee run on macOS?

The README does not document a macOS install path. It notes that Tracee should run on most common Linux distributions and kernels, and directs Mac users to a separate FAQ page before they try the Docker quickstart.

What privileges does Tracee need to run?

The Docker quickstart uses --privileged together with --pid=host and --cgroupns=host, and the Kubernetes install deploys a DaemonSet, which means one privileged pod per node. Clusters that forbid privileged workloads cannot run it without a policy change.

Official sources

  1. aquasecurity/tracee on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/aquasecurity-tracee.svg)](https://hysenlabs.com/projects/aquasecurity-tracee)