Falco: How to Bring Your Container Security to Another Level

Falco: How to Bring Your Container Security to Another Level


The only guide you need to understand the container runtime security with Falco 🐳

🚀 Intro

Container security is definitely a hot topic these days, ranging from preventing container escapes and hardening Kubernetes clusters to improving runtime detection and response capabilities.

I have been looking into this area for some time and experimenting with various techniques and technologies. To improve my container security, I have been hardening my Docker images by scanning them with Grype and Trivy and reviewing Dockerfiles more thoroughly. I have also been improving Docker run scripts by removing capabilities, defining custom AppArmor profiles, and setting the container filesystem to read-only. In other words, I tried to shift left my security as much as I could, hoping to reduce the attack surface.

But I was still missing one important piece: monitoring. How can we make sure that, even after deployment, our containers are running securely?

This article is part of a longer series on Docker engineering, but at BecomeDevops we regularly write about all DevOps-related technologies. You can read about Ansible, Jenkins or Kubernetes projects on our blog.




While most of the security measures I’ve implemented are about prevention — Falco covers our infrastructure from a detection point of view.

Consequently, in today’s article I will outline everything you need to know about Falco — a security camera for your infrastructure.


1️⃣⁠ ⁠Let’s start with the basics

OK, here’s what you need to know about Falco:

  • Created by Sysdig (the same team that wrote Wireshark)

  • Graduated project of the Cloud Native Computing Foundation

  • Integrates with VMs, containers, or Kubernetes clusters

  • It is an open-source project

  • Provides real-time monitoring

  • Due to utilization of eBPF — Falco has little performance impact on our infrastructure

  • If you are into Cloud-native certifications — it is also part of the official CKS curriculum


❌Falco is not:

  • ❌ A vulnerability scanner

  • ❌ Static security checker

  • ❌ This is not supply chain tool

Now, let’s quickly discuss Falco’s architecture.


But how exactly does Falco work? It uses a kernel module or eBPF to tap into the stream of Linux system calls in real time, comparing them against a customisable rules engine to detect suspicious behavior like unauthorised file access or unexpected process execution.

Falco is effectively both a policy engine and data-collection solution.



2️⃣⁠ Discussing the rules

Now, let’s talk about how to run Falco and what it looks like in practice.

The first thing we should analyse is the rules. Falco is shipped with a set of default rules. We can find these in the following folder:

/etc/falco/falco_rules.local.yaml
/etc/falco/falco_rules.local.yaml
/etc/falco/falco_rules.local.yaml


The example rules Falco is shipped with

However, the real power engine are the custom rules we can write based on the following template:


There are a few fields we need to discuss:

  1. rule: here we put the title/name of the rule

  2. desc: short, human-readable description of the rule

  3. condition: what is the rule we want to create here?

  4. output: what is the message we want to read once the rule is hit/matched?

  5. priority: we can assign a specific priority for the rule



3️⃣ Working with Falco

After installation (you can install Falco with apt-get, helm) we can see whether Falco is working by typing:

systemctl status falco
systemctl status falco
systemctl status falco

We should get the following output:


Ok, so let’s take an exemplary case. We would like to be notified every time there is a usage of wget or curl in our container. The rule can be as follows:

- rule: Curl detected in Container  desc: Detects execution of curl or wget inside a container  condition: >    evt.type = execve and    container.id != host and    proc.name in (curl, wget)  output: >    DOWNLOAD TOOL DETECTED |    user=%user.name container=%container.name cmd=%proc.cmdline  priority: WARNING
- rule: Curl detected in Container  desc: Detects execution of curl or wget inside a container  condition: >    evt.type = execve and    container.id != host and    proc.name in (curl, wget)  output: >    DOWNLOAD TOOL DETECTED |    user=%user.name container=%container.name cmd=%proc.cmdline  priority: WARNING
- rule: Curl detected in Container  desc: Detects execution of curl or wget inside a container  condition: >    evt.type = execve and    container.id != host and    proc.name in (curl, wget)  output: >    DOWNLOAD TOOL DETECTED |    user=%user.name container=%container.name cmd=%proc.cmdline  priority: WARNING

Great! We have our rule ready. Let’s try to trigger it by executing:

falco -r falco_rules.local.yaml
falco -r falco_rules.local.yaml
falco -r falco_rules.local.yaml
sudo falco -r falco_rules.local.yamlFri Jun 12 12:45:29 2026: Falco version: 0.43.1 (x86_64)Fri Jun 12 12:45:29 2026: Falco initialized with configuration files:Fri Jun 12 12:45:29 2026: /etc/falco/config.d/engine-kind-falcoctl.yaml | schema validation: okFri Jun 12 12:45:29 2026: /etc/falco/config.d/falco.container_plugin.yaml | schema validation: okFri Jun 12 12:45:29 2026: /etc/falco/falco.yaml | schema validation: okFri Jun 12 12:45:29 2026: System info: Linux version 6.17.0–1013-aws (buildd@lcy02-amd64–120) (x86_64-linux-gnu-gcc-13 (Ubuntu 13.3.0–6ubuntu2~24.04.1) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #13~24.04.1-Ubuntu SMP Fri Apr 24 21:50:45 UTC 2026Fri Jun 12 12:45:29 2026: Loaded plugin 'container@0.6.4' from file /usr/share/falco/plugins/libcontainer.soFri Jun 12 12:45:29 2026: [libs]: container: Enabled 'podman' container engine.Fri Jun 12 12:45:29 2026: [libs]: container: * enabled container runtime socket at '/run/podman/podman.sock'Fri Jun 12 12:45:29 2026: [libs]: container: Enabled 'docker' container en
sudo falco -r falco_rules.local.yamlFri Jun 12 12:45:29 2026: Falco version: 0.43.1 (x86_64)Fri Jun 12 12:45:29 2026: Falco initialized with configuration files:Fri Jun 12 12:45:29 2026: /etc/falco/config.d/engine-kind-falcoctl.yaml | schema validation: okFri Jun 12 12:45:29 2026: /etc/falco/config.d/falco.container_plugin.yaml | schema validation: okFri Jun 12 12:45:29 2026: /etc/falco/falco.yaml | schema validation: okFri Jun 12 12:45:29 2026: System info: Linux version 6.17.0–1013-aws (buildd@lcy02-amd64–120) (x86_64-linux-gnu-gcc-13 (Ubuntu 13.3.0–6ubuntu2~24.04.1) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #13~24.04.1-Ubuntu SMP Fri Apr 24 21:50:45 UTC 2026Fri Jun 12 12:45:29 2026: Loaded plugin 'container@0.6.4' from file /usr/share/falco/plugins/libcontainer.soFri Jun 12 12:45:29 2026: [libs]: container: Enabled 'podman' container engine.Fri Jun 12 12:45:29 2026: [libs]: container: * enabled container runtime socket at '/run/podman/podman.sock'Fri Jun 12 12:45:29 2026: [libs]: container: Enabled 'docker' container en
sudo falco -r falco_rules.local.yamlFri Jun 12 12:45:29 2026: Falco version: 0.43.1 (x86_64)Fri Jun 12 12:45:29 2026: Falco initialized with configuration files:Fri Jun 12 12:45:29 2026: /etc/falco/config.d/engine-kind-falcoctl.yaml | schema validation: okFri Jun 12 12:45:29 2026: /etc/falco/config.d/falco.container_plugin.yaml | schema validation: okFri Jun 12 12:45:29 2026: /etc/falco/falco.yaml | schema validation: okFri Jun 12 12:45:29 2026: System info: Linux version 6.17.0–1013-aws (buildd@lcy02-amd64–120) (x86_64-linux-gnu-gcc-13 (Ubuntu 13.3.0–6ubuntu2~24.04.1) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #13~24.04.1-Ubuntu SMP Fri Apr 24 21:50:45 UTC 2026Fri Jun 12 12:45:29 2026: Loaded plugin 'container@0.6.4' from file /usr/share/falco/plugins/libcontainer.soFri Jun 12 12:45:29 2026: [libs]: container: Enabled 'podman' container engine.Fri Jun 12 12:45:29 2026: [libs]: container: * enabled container runtime socket at '/run/podman/podman.sock'Fri Jun 12 12:45:29 2026: [libs]: container: Enabled 'docker' container en

In the logs, we should get the following alarms:


Now that we understand how to write a basic Falco rule, it’s worth taking a closer look at several essential commands that are extremely helpful in real production environments.

These commands allow you to validate rules, inspect available fields, debug detection logic, and ensure that Falco behaves exactly as expected before you deploy changes to your cluster. All very useful during daily work as a DevOps/Platform Engineer:

  1. falco --validate /etc/falco/falco_rules.local.yaml allows you to validate the rules before deploying them

  2. falco -list fields — When writing or debugging rules, it’s crucial to know which fields Falco exposes.

🚀 Outro

Falco is an excellent tool for monitoring and protecting container, pod, and VM infrastructure at runtime. By analyzing system calls in real time and comparing them against powerful, customizable rules, it gives teams deep visibility into what is happening inside their workloads — exactly when it matters most.

Whether you’re securing Kubernetes clusters, hardening Linux hosts, or building a modern cloud‑native security stack, Falco delivers the kind of actionable insights that traditional tools simply can’t provide. With proper rule tuning, validation, and continuous monitoring, it becomes a reliable guardian for your production environment.


Test us in action. Book a free
consultation for your team

We don't do hard sales pitches. Let's spend 30 minutes discussing your current DevOps bottlenecks, and we'll help you map out the most efficient upskilling path for your team.

Test us in action. Book a free consultation for your team

We don't do hard sales pitches. Let's spend 30 minutes discussing your current DevOps bottlenecks, and we'll help you map out the most efficient upskilling path for your team.