Install via Helm
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
# Install with the modern_ebpf driver (no kernel modules needed)
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set driver.kind=modern_ebpf \
--set tty=true \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=true
Falco runs as a DaemonSet (one pod per node). Falcosidekick is the alerting fanout (sends events to Slack / webhook / Loki / SIEM / etc.); its Web UI is a real-time event browser.
Verify it's running
kubectl -n falco get pods
# falco-XXXX Running
# falco-XXXX Running (one per node)
# falcosidekick-...
# falcosidekick-ui-...
kubectl -n falco logs ds/falco -f
# Real-time events stream out
Trigger a built-in rule
The default rule set ("falco rules") includes dozens of detections. Easiest to demo: spawn a shell inside a running container:
kubectl run nginx --image=nginx
kubectl exec -it nginx -- bash
# In Falco's logs / Falcosidekick UI:
# 19:21:34.123: Notice A shell was spawned in a container with an attached terminal
# (user=root container_id=abc shell=bash parent=runc)
Falco caught the exec bash via the syscall trace and matched the "Terminal shell in container" rule.
The rule language
# /etc/falco/falco_rules.local.yaml (override / extend the defaults)
- rule: Sensitive file opened for reading by non-trusted program
desc: "Detect attempts to read sensitive files like /etc/passwd by unexpected processes"
condition: >
open_read
and sensitive_files
and proc.name in (cat, less, tail, head, sh, bash, zsh)
and not user_known_sensitive_file_reader
output: >
Sensitive file read by potentially suspicious process
(user=%user.name file=%fd.name proc=%proc.name container=%container.name)
priority: WARNING
tags: [filesystem, mitre_credential_access]
- macro: sensitive_files
condition: fd.name in (/etc/shadow, /etc/sudoers, /root/.ssh/id_rsa, /root/.aws/credentials)
- list: user_known_sensitive_file_reader
items: [trusted-monitoring-agent, vault-agent]
Rules combine:
- Conditions built from event fields (proc, fd, container, k8s, syscall args)
- Macros for reusable predicate fragments
- Lists for "this process is allowed" allow-lists
Mature rule library at falco.org/docs.
The default rule categories
- Container drift — new executables not in the original image written to running containers (suggests post-exploit dropper).
- Privilege escalation —
setuidsyscalls,sudousage, kernel module loading. - Sensitive file access —
/etc/shadow, SSH keys, cloud-provider credential files. - Anomalous process — shells in containers, package managers running post-deploy, crypto-miner binaries (matched by hash / name).
- Network anomalies — outbound connections to known-bad IPs, unexpected listening ports.
- Mitre ATT&CK-tagged — every rule maps to relevant MITRE techniques for SOC integration.
Falcosidekick: where alerts go
Falco emits events; Falcosidekick fans them out to ~50 destinations. The popular picks:
# Helm values
falcosidekick:
enabled: true
config:
slack:
webhookurl: https://hooks.slack.com/services/...
minimumpriority: warning
messageformat: long
loki:
hostport: http://loki.monitoring.svc:3100
minimumpriority: notice
webhook:
address: https://my-soc.example.com/webhook
elasticsearch:
hostport: https://elastic.example.com:9200
index: falco
webui:
enabled: true
redis:
enabled: true
Falcosidekick UI (port-forward port 2802) is a live event browser; useful for first-time tuning to see what's actually firing.
Response automation: Falcosidekick → action
Falcosidekick can trigger responses (Falco "response engine"):
- Kill the offending pod (via Argo Workflows or a Kubernetes API call)
- Cordon the node where suspicious activity originated
- Snapshot the container's filesystem for forensics
- Apply a NetworkPolicy to isolate the pod
For "shell spawned in production container → kill pod immediately," wire Falcosidekick to a webhook that invokes kubectl delete pod <name> through a service account with that limited permission.
Custom rules: your application's threat model
# If your app should NEVER read its own backup files
- rule: App reading backup files
desc: "myapp should never read /backup/* — only the backup container should"
condition: >
open_read
and fd.name startswith "/backup/"
and container.name = "myapp"
output: "Suspicious backup read by app (file=%fd.name container=%container.name)"
priority: CRITICAL
# Network connection to an unexpected destination
- rule: App connecting to unexpected hosts
desc: "myapp should only connect to known internal services"
condition: >
outbound
and container.name = "myapp"
and not (fd.sip in (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16))
output: "External connection from myapp to %fd.sip:%fd.sport"
priority: WARNING
Tuning: the false-positive problem
Default rules fire on a lot of normal-but-suspicious activity. Tuning is required for production:
- Start with all alerts going to a low-priority channel (Loki / Elasticsearch).
- Watch for a week; categorize firing rules into "real threats / expected behavior / noise."
- Add macros / lists to allow-list legitimate sources.
- Promote tuned rules to high-priority channels (Slack / PagerDuty).
Skip this and Falco will drown the team in noise within a day.
Falco vs Tetragon
- Falco — longer-established; CNCF-graduated; declarative rule language; strong ecosystem (Falcosidekick fanout); detection-focused.
- Tetragon (sister project to Cilium; see Cilium tutorial) — also eBPF-based; can enforce at the kernel level (block syscalls, kill processes) in addition to detect; tighter Cilium integration; smaller rule library.
For pure detection + SIEM integration, Falco. For "I want to enforce policy in the kernel, not just alert," Tetragon. Both can coexist.
Worth knowing
- Performance. Modern_ebpf driver is low-overhead (~1-3% CPU at moderate event rates). The legacy kernel-module driver was heavier but is still available for older kernels.
- Node coverage matters. Falco runs per-node; if your cluster has nodes with kernels too old for modern eBPF support, those nodes won't have runtime detection.
- Cloud managed K8s (EKS / GKE / AKS) — some restrict eBPF; check before deploying Falco there.