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 escalationsetuid syscalls, sudo usage, 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:

  1. Start with all alerts going to a low-priority channel (Loki / Elasticsearch).
  2. Watch for a week; categorize firing rules into "real threats / expected behavior / noise."
  3. Add macros / lists to allow-list legitimate sources.
  4. 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.