Falco rules that catch real attacks (and skip the noise)
Default rulesets page you for everything. Tune Falco to the syscalls that matter and route the rest to a dashboard.
Falco watches the kernel's syscall stream and fires when something matches a rule — a shell in a container, a write under /etc, an outbound connection from a database pod. The problem is not detection; it is that the default ruleset alerts on so much benign activity that the real signal drowns. A pager that cries wolf gets muted, and a muted detector is no detector at all. Tuning is not optional — it is the difference between runtime security and runtime spam.
This note builds one high-confidence rule, carves a narrow exception for known-good debug images, and routes alerts by priority so Notice events do not page on-call. For admission and runtime hardening together, see Kubernetes security & hardening.
Untuned default rules are a pager firehose. Tune before you page.
Start with one rule you trust. Expand coverage only after routing and exceptions are disciplined.
falco -r /etc/falco/rules.d/Falco initialized with 89 ruleswatching syscalls via modern eBPF probe ... 10:42:01 Warning Shell spawned in a container (user=root container=api-7f9c shell=bash parent=node)10:42:07 Notice Package mgmt launched in container (apk add) signal, not noise — nobody should be typing in prod containersA rule that catches what matters
Good rules describe behavior, not strings. 'A shell process, with a TTY, inside a container' is robust — it does not care whether the attacker used bash, sh, or busybox. Match on process lineage and container context, and emit fields you will actually need during triage: user, container name, parent process, full cmdline.
- rule: Terminal shell in containerdesc: An interactive shell was opened inside a containercondition: >spawned_process and containerand shell_procs and proc.tty != 0output: >Shell spawned in a container(user=%user.name container=%container.nameshell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)priority: WARNINGtags: [container, shell, mitre_execution]
Tune with exceptions, not the mute button
When a rule is noisy, the instinct is to disable it. Do not — that blinds you to the real event. Instead carve a narrow exception for the known-good source, so everything else still fires. Keep exceptions in version control with a comment naming who approved them and why; review them quarterly the same way you review firewall rules.
# a debug image your team uses on purpose — reviewed Q2 2026- list: allowed_shell_containersitems: ["registry.io/ci-debug", "registry.io/toolbox"]- rule: Terminal shell in containerappend: truecondition: and not container.image.repository in (allowed_shell_containers)
Route by priority
Not every alert deserves a 3am page. Send Critical and Warning to the on-call channel, and stream Notice/Informational to a dashboard or your SIEM. Falcosidekick fans a single Falco output stream out to Slack, Loki, and object storage at once — configure routing rules on priority so the pager only fires on behavior you would actually investigate at night.
On Kubernetes, run Falco as a DaemonSet so every node sees the same syscall stream. Enable the modern eBPF driver where your kernel supports it — fewer false positives from legacy kernel-module probes, and no DKMS headaches on managed node images. Baseline your cluster in Audit for a week before you route WARNING to PagerDuty.
Where this goes next
Detection is only half the loop — the other half is response. Falco Talon can act on an alert automatically (kill the pod, isolate it with a NetworkPolicy) while a human catches up. Start by trusting one high-confidence rule enough to auto-respond; expand from there. The Kubernetes security & hardening course covers runtime detection, admission control, and the full CKS surface.
Go deeper in a courseKubernetes security & hardeningRuntime detection, admission control and the full CKS surface.View course