Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Implements eBPF-based security monitoring using Cilium Tetragon for real-time process execution tracking, network connection observability, file access auditing, and runtime enforcement. Covers TracingPolicy CRD authoring with kprobe/tracepoint hooks, in-kernel filtering via matchArgs/matchBinaries selectors, JSON event export, and integration with SIEM pipelines. Use when building kernel-level runtime security observability for Linux hosts or Kubernetes clusters.
.claude/skills/implementing-ebpf-security-monitoring/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-07 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-02 | ✗→✓ | ▲ Improved | — | — |
| case-05 | ✗→✓ | ▲ Improved | — | — |
kubectl configured with cluster accesstetra CLI installed for local event streamingrequests, kubernetes, pyyaml dependenciesDeploy Tetragon via Helm to get default process lifecycle observability:
bashhelm repo add cilium https://helm.cilium.io helm repo update helm install tetragon cilium/tetragon -n kube-system \ --set tetragon.enableProcessCred=true \ --set tetragon.enableProcessNs=true
Verify the installation:
bashkubectl get pods -n kube-system -l app.kubernetes.io/name=tetragon kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon -c export-stdout -f | head -20
For non-Kubernetes Linux hosts, install from the tarball release:
bashcurl -LO https://github.com/cilium/tetragon/releases/latest/download/tetragon-linux-amd64.tar.gz tar xzf tetragon-linux-amd64.tar.gz sudo cp tetragon /usr/local/bin/ sudo cp tetra /usr/local/bin/ # Start tetragon daemon sudo tetragon --btf /sys/kernel/btf/vmlinux & # Stream events tetra getevents -o compact
Tetragon generates process_exec and process_exit events by default without any TracingPolicy:
bash# Stream process events in compact format tetra getevents -o compact # Stream in JSON for SIEM ingestion tetra getevents -o json | jq '.process_exec // .process_exit'
Example process_exec JSON event:
json{ "process_exec": { "process": { "binary": "/usr/bin/curl", "arguments": "https://malicious.example.com/payload", "cwd": "/tmp", "uid": 1000, "pod": { "namespace": "default", "name": "webapp-7b4d9f8c6-x2k9p" }, "parent": { "binary": "/bin/bash", "pid": 1234 } } } }
Create a TracingPolicy CRD to monitor access to sensitive files via the sys_openat kprobe:
yaml# file-access-monitor.yaml apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: monitor-sensitive-file-access spec: kprobes: - call: "fd_install" syscall: false args: - index: 0 type: "int" - index: 1 type: "file" selectors: - matchArgs: - index: 1 operator: "Prefix" values: - "/etc/shadow" - "/etc/passwd" - "/etc/sudoers" - "/root/.ssh/" - "/etc/kubernetes/pki/" matchActions: - action: Post
Apply and observe:
bashkubectl apply -f file-access-monitor.yaml tetra getevents -o compact --process-filter "event_set:PROCESS_KPROBE"
Monitor outbound TCP connections using the tcp_connect kprobe:
yaml# network-monitor.yaml apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: monitor-tcp-connections spec: kprobes: - call: "tcp_connect" syscall: false args: - index: 0 type: "sock" selectors: - matchActions: - action: Post
Detect setuid/setgid calls that may indicate privilege escalation:
yaml# privilege-escalation-detect.yaml apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: detect-privilege-escalation spec: kprobes: - call: "__sys_setuid" syscall: false args: - index: 0 type: "int" selectors: - matchArgs: - index: 0 operator: "Equal" values: - "0" matchActions: - action: Post - call: "commit_creds" syscall: false args: - index: 0 type: "cred" selectors: - matchActions: - action: Post
Block unauthorized binary execution by killing the process in-kernel:
yaml# enforce-binary-allowlist.yaml apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: enforce-no-crypto-miners spec: kprobes: - call: "sys_execve" syscall: true args: - index: 0 type: "string" selectors: - matchArgs: - index: 0 operator: "Postfix" values: - "xmrig" - "minerd" - "cpuminer" - "cryptonight" matchActions: - action: Sigkill
Configure Tetragon to export JSON events to a file sink for Fluentd/Filebeat/Vector ingestion:
bash# Helm values for file export helm upgrade tetragon cilium/tetragon -n kube-system \ --set tetragon.exportFilename=/var/log/tetragon/tetragon.log \ --set tetragon.exportFileMaxSizeMB=100 \ --set tetragon.exportFileMaxBackups=5
Then configure your log shipper (e.g., Filebeat) to tail /var/log/tetragon/tetragon.log and send to your SIEM.
Use TracingPolicyNamespaced to scope monitoring to specific namespaces:
yamlapiVersion: cilium.io/v1alpha1 kind: TracingPolicyNamespaced metadata: name: monitor-production-file-access namespace: production spec: kprobes: - call: "fd_install" syscall: false args: - index: 0 type: "int" - index: 1 type: "file" selectors: - matchArgs: - index: 1 operator: "Prefix" values: - "/etc/shadow" - "/etc/passwd"
yaml# reverse-shell-detect.yaml apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: detect-reverse-shells spec: kprobes: - call: "tcp_connect" syscall: false args: - index: 0 type: "sock" selectors: - matchBinaries: - operator: "In" values: - "/bin/bash" - "/bin/sh" - "/usr/bin/python3" - "/usr/bin/perl" - "/usr/bin/nc" - "/usr/bin/ncat" matchActions: - action: Post
yaml# container-escape-detect.yaml apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: detect-container-escape spec: kprobes: - call: "sys_openat" syscall: true args: - index: 0 type: "int" - index: 1 type: "string" selectors: - matchArgs: - index: 1 operator: "Prefix" values: - "/proc/1/root" - "/proc/1/ns" - "/sys/kernel/security" - "/proc/sysrq-trigger" matchActions: - action: Post - call: "sys_mount" syscall: true args: - index: 0 type: "string" - index: 1 type: "string" - index: 2 type: "string" selectors: - matchActions: - action: Post
bash# Use tetra CLI to pipe events through jq into Elasticsearch tetra getevents -o json | jq -c 'select(.process_kprobe != null)' | \ while IFS= read -r line; do curl -s -X POST "http://elasticsearch:9200/tetragon-events/_doc" \ -H "Content-Type: application/json" \ -d "$line" done
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 21 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.