Container Runtime Security: A Complete Guide to Falco, Seccomp, and AppArmor

Learn how to secure running containers with Falco runtime monitoring, seccomp system call filtering, and AppArmor mandatory access control. Includes code examples and production checklists.

Container Runtime Security: A Complete Guide to Falco, Seccomp, and AppArmor

The most dangerous moment for a container is not when it is being built. It is not when it is being deployed. It is while it is running. Image scanning catches vulnerabilities before deployment. Secure configuration prevents misconfigurations at build time. But after the container starts, a new class of threats emerges: process-level attacks, unauthorized system calls, privilege escalation attempts, and kernel exploits that try to break out of the container entirely.

Container runtime security is the practice of protecting containers while they are actively running. Unlike image scanning or static configuration analysis, runtime security operates in real time, detecting and blocking threats as they happen. In this guide, we cover the three essential layers of container runtime security — Falco, seccomp, and AppArmor — and show you exactly how to implement each one in production.

Why Image Scanning Alone Is Not Enough

Organizations invest heavily in image scanning, and for good reason. Scanning catches known CVEs, vulnerable packages, and misconfigurations before deployment. But image scanning has a fundamental blind spot: it cannot detect attacks that happen after the container starts. A container can pass every scan with flying colors and still be compromised through an application-level vulnerability that the scanner never flagged.

According to the 2025 Sysdig Cloud-Native Security Report, container runtime attacks increased by 180% year over year, and the average time to detect a runtime breach was 72 hours. During those three days, an attacker can exfiltrate data, move laterally to other containers, install backdoors, and establish persistence. Runtime security closes this gap by monitoring behaviors, not just configurations.

The three layers of runtime defense — Falco for behavioral monitoring, seccomp for system call filtering, and AppArmor for mandatory access control — form a defense-in-depth strategy that catches threats at every level of the container stack.

Container runtime security layers: Host OS, AppArmor/SELinux, seccomp, container with non-root user and read-only filesystem

Layer 1: Falco — Behavioral Runtime Monitoring

Falco is the de facto standard for container runtime security. Created by Sysdig and now a CNCF graduated project, Falco uses eBPF (Extended Berkeley Packet Filter) to monitor system calls in real time and alert on suspicious behavior. It is the container equivalent of a host-based intrusion detection system (HIDS), designed specifically for cloud-native environments.

What Falco Detects

  • Unusual process execution inside a container (e.g., a shell spawning in a web server)
  • File system modifications outside expected paths
  • Network connections to known malicious IPs or unexpected destinations
  • Privilege escalation attempts, including setuid binaries
  • Container escape techniques like mount namespace manipulation
  • Reads of sensitive files such as /etc/shadow or service account tokens

Installing and Configuring Falco

# Install Falco via Helm on Kubernetes
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco \
  --namespace falco --create-namespace \
  --set driver.kind=ebpf \
  --set falco.grpc.enabled=true

# Or install directly on Docker hosts
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | \
  sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" | \
  sudo tee -a /etc/apt/sources.list.d/falcosecurity.list
sudo apt-get update && sudo apt-get install -y falco

Writing Custom Falco Rules

Falco ships with a comprehensive set of default rules, but production environments need custom rules tailored to your specific application behaviors.

# Custom rule: Alert when a shell spawns in a web container
- rule: Shell Spawned in Web Container
  desc: A shell was executed inside a container running a web server
  condition: >
    spawned_process and container
    and container.image.repository contains "nginx"
    and proc.name in (bash, sh, zsh, dash)
  output: >
    Shell spawned in web container
    (user=%user.name container=%container.id
     image=%container.image proc=%proc.name cmdline=%proc.cmdline)
  priority: CRITICAL
  tags: [container, shell, web]

Deploy custom rules by mounting them into the Falco pod. Falco automatically reloads rules when the configuration file changes, so there is no need to restart the Falco service for rule updates.

Layer 2: Seccomp — System Call Filtering

Seccomp (secure computing mode) is a Linux kernel feature that restricts the system calls a process can make. A typical container needs only about 50 of the 300+ available Linux system calls. Every system call beyond what the application actually uses is unnecessary risk, because it represents a code path that an attacker could exploit to interact with the kernel.

How Seccomp Works with Docker

Docker applies a default seccomp profile that blocks approximately 44 dangerous system calls, including unshare, kexec_file_load, and bpf. This default profile is a good baseline, but it is generic. For production containers, you should create custom seccomp profiles that allow only the system calls your application needs.

# Generate a seccomp profile for your application
# Run the container and trace system calls for 30 seconds
docker run --rm -it \
  --security-opt seccomp=unconfined \
  myapp:latest &
sleep 30
docker inspect $(docker ps -ql) \
  --format '{{.State.Pid}}' | \
  xargs strace -c -p

# Or use dockersec to generate a profile automatically
docker run --rm -it \
  --security-opt seccomp=profile.json \
  myapp:latest

Applying a Custom Seccomp Profile

# Docker: apply a seccomp profile at runtime
docker run --rm \
  --security-opt seccomp=/path/to/profile.json \
  myapp:latest

# Kubernetes: specify seccomp in pod security context
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    seccompProfile:
      type: Localhost
      localhostProfile: profiles/audit.json
  containers:
  - name: app
    image: myapp:latest

Start with theaudit mode (non-blocking) to log all system calls your application makes, then generate a profile that allows only those calls. Test thoroughly before switching to enforce mode. Missing a required system call in your profile will crash the application.

Layer 3: AppArmor — Mandatory Access Control

AppArmor (Application Armor) is a Linux Security Module (LSM) that confines programs to a limited set of resources. Unlike seccomp which filters system calls, AppArmor controls what files, networks, and capabilities a process can access. It is the container equivalent of a firewall for system resources.

AppArmor Profiles for Containers

Docker ships with a default AppArmor profile for containers, but like the seccomp default, it is generic. For production, create custom AppArmor profiles that restrict file access, network operations, and capability usage to exactly what the application needs.

#include profile myapp-flags flags=(attach_disconnected,mediate_deleted) {
  #include# Network access
  network inet tcp,
  network inet udp,

  # Filesystem access
  /app/** r,
  /app/data/** rw,
  /tmp/** rw,

  # Deny everything else
  deny /etc/shadow r,
  deny /proc/** w,
  deny /sys/** w,

  # Capabilities
  capability setgid,
  capability setuid,
  capability net_bind_service,
}

Loading and Applying AppArmor Profiles

# Load the profile into the kernel
sudo apparmor_parser -r -W /etc/apparmor.d/myapp-profile

# Docker: apply the AppArmor profile
docker run --rm \
  --security-opt apparmor=myapp-profile \
  myapp:latest

# Kubernetes: specify AppArmor via annotation
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  annotations:
    container.apparmor.security.beta.kubernetes.io/app: localhost/myapp-profile
spec:
  containers:
  - name: app
    image: myapp:latest

Useaa-complain mode initially to log violations without blocking, then switch to aa-enforce once you have validated the profile against real application traffic.

Putting the Three Layers Together

Falco, seccomp, and AppArmor operate at different levels of the container stack:

  • Falcomonitors behavior and alerts on anomalous events — the intrusion detection layer.
  • Seccompfilters system calls at the kernel boundary — the system call firewall.
  • AppArmorcontrols resource access at the application level — the mandatory access control layer.

Together, they form a defense-in-depth strategy that protects containers before, during, and after an attack. Falco tells you something suspicious is happening. Seccomp prevents the attacker from using the system calls needed to exploit the kernel. AppArmor blocks access to sensitive files and resources even if the attacker has code execution inside the container.

Container runtime security with Falco, seccomp, and AppArmor layers protecting a running container

Container Runtime Security Checklist

  • ⬜ Falco is installed and running on all cluster nodes or Docker hosts
  • ⬜ Default Falco rules are enabled and tuned for your environment
  • ⬜ Custom Falco rules exist for your application-specific behaviors
  • ⬜ Falco alerts are forwarded to a SIEM or centralized logging system
  • ⬜ A custom seccomp profile is generated for each application
  • ⬜ Seccomp profiles are tested in audit mode before enforcement
  • ⬜ An AppArmor profile is defined for each production container
  • ⬜ Profiles are loaded and validated in complain mode first
  • ⬜ Containers run as non-root users with read-only filesystems
  • ⬜ Linux capabilities are dropped to the minimum required set
  • ⬜ Runtime security events are included in incident response drills
  • ⬜ Falco, seccomp, and AppArmor configurations are version-controlled

Frequently Asked Questions

Do I need all three runtime security layers?

Ideally, yes. Each layer addresses a different attack vector. If resources are limited, start with Falco (detection), then add seccomp (system call control), and finally AppArmor (access control). The combination is significantly stronger than any single layer.

Will runtime security affect application performance?

Falco's eBPF-based monitoring has minimal overhead, typically less than 2% CPU. Seccomp and AppArmor have negligible performance impact because they operate on kernel-level policies that are checked during system call dispatch. Performance regression testing is still recommended before production deployment.

Can I use SELinux instead of AppArmor?

Yes. SELinux provides similar mandatory access control to AppArmor but uses a different labeling model. AppArmor is more common on Debian-based systems and Docker hosts, while SELinux is standard on Red Hat Enterprise Linux and Fedora. Choose the one that matches your host operating system.

How do I test runtime security rules?

Run a penetration test that simulates container escape attempts, shell injection, and sensitive file reads. Falco should alert on all of them. Seccomp should block the system calls needed for the escape. AppArmor should prevent access to protected files. Document the gaps and iterate.

What is the most common container runtime attack?

Cryptocurrency mining is the most frequently detected runtime attack. Attackers compromise a container through a vulnerable application, then download and run a miner. Falco's default rules detect this immediately through the unexpected execution of a binary likexmrig or cpuminer.

Conclusion

Container runtime security is the last line of defense in your container security strategy. Image scanning, secure configuration, and network policies all reduce risk, but they cannot prevent runtime attacks. Falco, seccomp, and AppArmor give you the tools to detect, block, and contain those attacks when they happen.

Start with Falco for visibility into what is happening in your containers. Add seccomp profiles to restrict system calls to the minimum each application needs. Finally, layer AppArmor or SELinux to control resource access. The three layers together provide comprehensive runtime protection that catches threats image scanning never will.

If you are unsure where to start, deploy Falco in monitoring mode first. The alerts it generates will show you exactly which runtime behaviors exist in your environment, and those are the ones to lock down first with seccomp and AppArmor.

Ready to apply these concepts?

Try ShieldOps AI and start scanning your infrastructure right away.

Start Free Scan

Your take

Rate this article or leave a comment

Have more questions? Check our

FAQ
🤖