Falco for Kubernetes Security — CKS Certification Scenarios Explained

A hands-on Falco tutorial by Saiyam Pathak (Kubesimplify, March 2025) that teaches cloud-native runtime security through three exam-style scenarios from the Certified Kubernetes Security Specialist (CKS) curriculum: detecting Pods that access /dev/mem with a custom rule, running Falco directly on a host, and modifying built-in rule outputs. Companion repo: saiyam1814 on GitHub.

What Falco Is and How It Works

Falco is a cloud-native runtime security project: started in 2016 by Sysdig, donated to the CNCF in 2018, and now a CNCF Graduated project — the de facto standard for Kubernetes runtime security. The core insight is that every application talks to the kernel through system calls, so observing syscalls gives you a complete, tamper-resistant view of workload behavior. Falco taps the syscall stream, parses each event against a set of rules, and raises an alert whenever a rule’s condition is violated.

Architecturally Falco splits into two planes:

  • Kernel space (drivers): an eBPF probe on modern kernels (or a kernel module on older ones) captures syscall events and passes them up through a ring buffer.
  • User space (engine): the Falco engine enriches events with container/Kubernetes metadata, evaluates them against the default rule set plus any custom rules, and emits alerts.

Inputs can be extended beyond syscalls with Kubernetes audit logs and plugins (e.g., cloud API logs). Outputs go to stdout, syslog, gRPC, Prometheus, or HTTP — and via HTTP to Falcosidekick, which fans alerts out to Slack, S3, Loki, and dozens of other sinks.

Falco can be installed two ways, and the CKS exam expects fluency in both: as a DaemonSet on the cluster (via Helm), or directly on the host (apt package on a node), where rules live in /etc/falco/.

Scenario 1: Detecting Pods Accessing /dev/mem

Three deployments run in the cluster; one is “crazy” and reads /dev/mem. The task is to find and remove it.

  1. Install Falco as a DaemonSet: helm repo add falcosecurity … && helm install falco falcosecurity/falco -n falco. In the exam Falco is usually pre-installed.
  2. Write a custom rule (custom-rules.yaml). Rule anatomy: rule name, desc, condition, output, priority, tags. The condition uses fields from the Falco documentation’s supported fields reference — the key document to search both in practice and in the exam:
    • fd.name — for every syscall with a file-descriptor argument, the full path if the FD is a file (so fd.name = /dev/mem).
    • evt.type — the syscall event type (open, openat).
    • Output fields like proc.cmdline, user.name, container.id, container.image.repository, k8s.pod.name identify the culprit.
  3. Load the rule into the DaemonSet: create a ConfigMap from the rules file (kubectl create configmap falco-custom-rules --from-file=custom-rules.yaml -n falco), then kubectl edit daemonset to add a volume + volumeMounts wiring the ConfigMap into the Falco pods, and trigger a rolling restart.
  4. Hunt: kubectl logs -n falco -l <falco-label> | grep /dev/mem reveals a cat process running as root in a busybox container — with k8s.pod.name pointing at demo3. kubectl delete deploy demo3 removes the offender.

The loop — write rule → load rule → read alert → map alert to Pod → delete workload — is the canonical CKS Falco workflow.

Scenario 2: Falco on the Host with a Custom Rule

Falco also runs as a plain Linux service on a node (installed via apt on the control-plane node in the demo). Three files matter under /etc/falco/:

FileRole
falco.yamlEngine configuration — outputs (e.g. syslog_output enabled), driver settings
falco_rules.yamlThe predefined, default rule set — edit in place only when a scenario demands it
falco_rules.local.yamlYour local/custom rules — the correct place for new rules on a host install

The same /dev/mem detection rule is dropped into falco_rules.local.yaml and Falco is run from the CLI: falco -M <seconds> runs the engine for a bounded duration (handy for capturing evidence to a log file). When the workload executes, Falco prints alerts every couple of seconds with the container ID. Because the host install has no Kubernetes metadata enrichment, the container ID is mapped back to a Pod with crictl ps | grep <id> — revealing demo3 again.

Scenario 3: Modifying Falco Rule Outputs

The third scenario (run on a Docker playground) demonstrates editing a built-in rule: find the rule for “a shell was spawned in a container” inside /etc/falco/falco_rules.yaml, and replace its output string with a custom format (timestamp, container ID, …) composed from the same supported-fields reference. After saving, run falco, then docker run -it ubuntu bash to spawn an attached shell — the alert now appears in the new format, with the container ID matching docker ps. Takeaway: default rules are fully editable, and output strings are just field interpolations.

CKS Exam Perspective

For the CKS exam the video’s advice is: know where rules live (ConfigMap + DaemonSet volumes on K8s; /etc/falco/falco_rules.local.yaml on hosts), know how to find condition fields (the supported-fields doc), know the falco -M CLI, and know how to go from alert → container ID → Pod (crictl ps). Falco scenarios are effectively guaranteed marks once the rule-editing mechanics are muscle memory.

See Also

Wiki Concepts

Creator / Entity

  • Saiyam Pathak — creator (Kubesimplify); part of his CKS certification series