Skip to content

Falco Runtime Security

Detect suspicious runtime behavior in your containers with Falco, the CNCF graduated threat detection engine.

Time: ~20 minutes Difficulty: Advanced

  • How Falco monitors system calls to detect threats
  • Triggering real security alerts: shell access, sensitive file reads, network activity
  • Reading Falco alerts in real time
  • Understanding Falco rules and how they match syscall patterns

Minikube driver note: Falco uses eBPF to hook into the Linux kernel. The Docker driver wraps everything in a container, which blocks eBPF access. Falco requires --driver=kvm2 or --driver=qemu2.

Check your current driver:

Terminal window
minikube profile list

If you see docker in the DRIVER column, you have two options:

Option A: Create a separate profile (keeps your existing cluster):

Terminal window
minikube start -p falco-lab --driver=qemu2 --cpus=4 --memory=8192

When done, switch back: minikube profile minikube

Option B: Recreate your cluster with a compatible driver:

Terminal window
minikube delete
minikube start --driver=qemu2 --cpus=4 --memory=8192 --disk-size=40g
minikube addons enable ingress
minikube addons enable metrics-server

Install Falco via Helm:

Terminal window
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco \
--namespace falco-system \
--create-namespace \
--set tty=true \
--set falcosidekick.enabled=false \
--set driver.kind=modern_ebpf \
--set resources.limits.memory=2Gi \
--set resources.requests.memory=512Mi

Wait for Falco to be ready:

Terminal window
kubectl rollout status daemonset/falco -n falco-system

Navigate to the demo directory:

Terminal window
cd demos/falco

Create the namespace and target application:

Terminal window
kubectl apply -f manifests/namespace.yaml
kubectl apply -f manifests/target-app.yaml

Check that Falco is logging events:

Terminal window
kubectl logs -l app.kubernetes.io/name=falco -n falco-system --tail=5

You should see Falco initialization messages or event logs.

This is the core of the demo. Open two terminals for this section.

In the first terminal, watch Falco logs in real time:

Terminal window
kubectl logs -l app.kubernetes.io/name=falco -n falco-system -f

Keep this running.

In the second terminal, run these commands and watch the alerts appear in Terminal 1.

Terminal window
kubectl exec -it deployment/web-app -n falco-demo -- /bin/sh

Switch to Terminal 1. Falco fires “Terminal shell in container” alert.

Type exit to leave the shell.

Terminal window
kubectl exec deployment/web-app -n falco-demo -- cat /etc/shadow

Watch Terminal 1. Falco fires “Read sensitive file untrusted” alert.

Terminal window
kubectl exec deployment/web-app -n falco-demo -- touch /bin/malicious

Watch Terminal 1. Falco fires “Write below binary dir” alert with ERROR priority.

Terminal window
kubectl exec deployment/web-app -n falco-demo -- wget -qO- http://example.com

Falco may fire alerts for unexpected network tool usage.

manifests/
namespace.yaml # falco-demo namespace
target-app.yaml # Simple nginx app: Deployment + Service (2 replicas)

Falco runs as a DaemonSet on every node (one pod per node). It hooks into the Linux kernel via eBPF to monitor every system call made by processes in containers.

The detection pipeline:

Your Action -> Kernel Syscall -> Falco Rule Match -> Alert
kubectl exec sh -> execve() -> "Terminal shell" -> WARNING
cat /etc/shadow -> open() -> "Sensitive file" -> WARNING
touch /bin/malicious -> open(O_CREAT) -> "Write below /bin" -> ERROR
wget ... -> execve() -> "Network tool" -> WARNING

How Falco rules work:

When a syscall matches a rule condition, Falco generates an alert. For example:

  • Rule: “Terminal shell in container”
  • Condition: process spawned in container + process name is sh or bash
  • Priority: WARNING
  • Output: Timestamp, container ID, pod name, namespace, command, user

The alert includes rich context: which pod, which container, what command, which user, and more. This makes it easy to investigate incidents.

Falco vs preventive security:

  • Kyverno/OPA: Prevent bad configs from being deployed (admission control)
  • Trivy/Grype: Scan images for vulnerabilities before deployment
  • Falco: Detect threats at runtime, after the container is running

You need all three layers for defense in depth.

  1. Trigger package manager alert:

    Terminal window
    kubectl exec deployment/web-app -n falco-demo -- apk add curl

    Falco detects package management in containers.

  2. Inspect Falco’s built-in rules:

    Terminal window
    kubectl exec -n falco-system daemonset/falco -- cat /etc/falco/falco_rules.yaml | head -100

    Scroll through to see default rules like “Write below root”, “Contact K8s API Server From Container”, and more.

  3. Check all Falco events in the last 5 minutes:

    Terminal window
    kubectl logs -l app.kubernetes.io/name=falco -n falco-system --since=5m | grep "Warning\|Error"
  4. Create a pod without securityContext and watch additional alerts:

    Terminal window
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
    name: test-pod
    namespace: falco-demo
    spec:
    containers:
    - name: app
    image: nginx:1.25.3-alpine
    EOF

    Run kubectl exec -it test-pod -n falco-demo -- /bin/sh and watch Falco fire alerts.

  5. Write a custom Falco rule:

    Create a ConfigMap with a custom rule to detect when someone reads /etc/passwd:

    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: falco-custom-rules
    namespace: falco-system
    data:
    custom-rules.yaml: |
    - rule: Read Passwd File
    desc: Detect reads to /etc/passwd
    condition: >
    evt.type = open and
    fd.name = /etc/passwd and
    container.id != host
    output: "Passwd file read (user=%user.name command=%proc.cmdline file=%fd.name container=%container.name)"
    priority: WARNING

    Apply it and configure Falco to load it via Helm values.

Delete the demo namespace:

Terminal window
kubectl delete namespace falco-demo

To remove Falco itself:

Terminal window
helm uninstall falco -n falco-system
kubectl delete namespace falco-system

See docs/deep-dive.md for a detailed explanation of how eBPF works, Falco’s rule engine, alert pipelines, integration with Falcosidekick for Slack/PagerDuty alerting, and building a runtime security strategy.

Move on to OpenTelemetry & Distributed Tracing to see the full journey of a request across microservices with OpenTelemetry and Jaeger.