Container runtimes provide process isolation through namespaces and cgroups, but these mechanisms alone do not restrict what a container process can do on the host kernel. AppArmor (Application Armor) is a Linux Security Module (LSM) that enforces mandatory access control policies, restricting container processes to only the system resources they explicitly need.
This guide compares three approaches to managing AppArmor profiles for containers: standalone AppArmor utilities (apparmor-utils), Docker’s built-in AppArmor integration, and containerd’s native AppArmor profile support. We cover profile creation, deployment, and best practices for securing containerized workloads in self-hosted environments.
Understanding AppArmor for Containers
AppArmor works by attaching security profiles to processes via the Linux Security Module (LSM) framework. Each profile defines which files, network ports, and capabilities a process can access. For containers, AppArmor profiles are applied when the container runtime starts the container process.
Without AppArmor, a root process inside a container can potentially:
- Access sensitive host files through mount namespaces
- Load kernel modules if capabilities are not properly restricted
- Access raw sockets or perform network operations beyond what the container needs
- Modify system-wide settings via procfs or sysfs
AppArmor profiles restrict these operations at the kernel level, providing defense-in-depth beyond container runtime security settings.
| Feature | AppArmor Utils | Docker AppArmor | Containerd AppArmor |
|---|---|---|---|
| Package | apparmor-utils | docker-ce (built-in) | containerd (built-in) |
| Profile Location | /etc/apparmor.d/ | /etc/apparmor.d/ (or inline) | /etc/apparmor.d/ (or inline) |
| Profile Syntax | AppArmor DSL | AppArmor DSL | AppArmor DSL |
| Management CLI | aa-genprof, aa-enforce, aa-complain | docker run –security-opt | containerd CRI config |
| Default Profile | No (manual) | docker-default (included) | cri-default (CRI) |
| Custom Profiles | Yes | Yes | Yes |
| Profile Enforcement | Kernel LSM | Runtime-applied at container start | Runtime-applied at container start |
| Profile Switching | aa-enforce/aa-complain | Container restart required | Container restart required |
| Kubernetes Support | Manual | Via runtime config | Native (via CRI) |
| Best For | Host-level security | Docker environments | Kubernetes/containerd environments |
AppArmor Utils: Standalone Profile Management
apparmor-utils provides command-line tools for creating, managing, and enforcing AppArmor profiles. This approach is ideal for host-level container security management.
Installation
| |
Generating Profiles with aa-genprof
aa-genprof interactively generates profiles by monitoring an application’s behavior:
| |
Writing Custom AppArmor Profiles
Create a profile in /etc/apparmor.d/:
| |
Managing Profile States
| |
Docker AppArmor Integration
Docker includes a default AppArmor profile (docker-default) that provides a reasonable baseline for container security. Custom profiles can be applied per-container.
Default Docker AppArmor Profile
Docker ships with a default profile that:
- Allows basic system calls required by most containers
- Blocks access to
/proc/sys,/sys/fs, and other sensitive paths - Restricts kernel module loading
- Allows network access (TCP/UDP)
- Denies raw socket access
To check the default profile:
| |
Applying Custom AppArmor Profiles to Docker Containers
| |
Docker Compose with AppArmor
| |
Generating Docker-Specific Profiles
| |
Containerd AppArmor Support
containerd supports AppArmor profiles through its CRI (Container Runtime Interface) implementation. This is the primary mechanism for applying AppArmor in Kubernetes environments.
Configuring Default AppArmor in containerd
| |
Applying AppArmor Profiles via CRI
When using containerd directly (not through Kubernetes):
| |
Kubernetes AppArmor Integration
Kubernetes supports AppArmor through annotations:
| |
The runtime/default annotation applies the container runtime’s default profile (containerd’s cri-default or Docker’s docker-default). The localhost/profile-name annotation applies a custom profile from /etc/apparmor.d/.
Container AppArmor Profile for Database Services
Here’s a production-ready AppArmor profile for a database container:
| |
Docker Compose Full Stack with AppArmor
| |
Choosing the Right AppArmor Management Approach
| Scenario | Recommended Approach | Reason |
|---|---|---|
| Docker-only environment | Docker built-in profiles | Seamless integration, default profile included |
| Kubernetes clusters | Containerd AppArmor via annotations | Native CRI support, per-pod granularity |
| Mixed runtime environment | AppArmor utils (standalone) | Runtime-agnostic, works with any container engine |
| Custom security requirements | Custom profiles + aa-genprof | Fine-grained control over each service |
| Compliance (PCI, HIPAA) | Custom enforced profiles | Audit-ready, verifiable security policies |
For broader container sandboxing, see our container sandboxing comparison covering gVisor, Kata, and Firecracker. For container security hardening beyond access control, our Docker Bench vs Trivy vs Checkov guide covers automated security auditing. For seccomp-based syscall filtering, check our seccomp profile management article.
FAQ
What is AppArmor and why should I use it with containers?
AppArmor is a Linux Security Module that provides mandatory access control (MAC). It restricts what files, network ports, and capabilities a process can access. While container runtimes provide namespace and cgroup isolation, AppArmor adds kernel-level enforcement that prevents container escape even if a process gains root privileges inside the container. It is defense-in-depth for containerized workloads.
How does AppArmor differ from seccomp for container security?
AppArmor and seccomp serve different purposes. AppArmor controls what resources a process can access (files, network, capabilities). Seccomp controls which system calls a process can make. They are complementary: seccomp blocks dangerous syscalls (like mount, ptrace), while AppArmor restricts file and network access. Use both for comprehensive container security.
Can I use AppArmor profiles with Docker Compose?
Yes. Add security_opt: - apparmor=profile-name to each service in your docker-compose.yml. The profile must be loaded on the host system before starting the containers. Docker automatically applies the profile when creating the container.
How do I create an AppArmor profile for my application?
Use aa-genprof /path/to/binary to start interactive profile generation. Run your application normally, and aa-genprof will monitor all access attempts. When the application tries to access a resource, aa-genprof prompts you to allow or deny the access. After completing the session, save the profile and switch to enforce mode.
What happens if an AppArmor profile blocks a legitimate container operation?
Switch the profile to complain mode with aa-complain profile-name. In complain mode, violations are logged but not blocked. Review the logs with aa-logprof to identify which rules need adjustment. Once the profile is correct, switch back to enforce mode with aa-enforce profile-name.
Are AppArmor profiles shared across containers?
Yes. AppArmor profiles are defined at the host level and can be applied to any container. Multiple containers can use the same profile, or each container can have its own profile. Profiles are loaded into the kernel once and reused.
How do I verify AppArmor is active on my system?
Run aa-status to see loaded profiles and their enforcement state. Check cat /sys/kernel/security/lsm to see if AppArmor is in the active LSM list. Also check dmesg | grep apparmor for kernel-level AppArmor messages.
Why Self-Host Container Security?
Self-hosted container environments require security controls that match or exceed managed cloud offerings. AppArmor provides enterprise-grade mandatory access control without additional infrastructure or licensing costs. Combined with seccomp profiles, read-only filesystems, and dropped capabilities, AppArmor forms a critical layer in container security hardening.
For organizations running self-hosted Kubernetes, AppArmor profiles complement Kubernetes Pod Security Standards by providing host-level enforcement that survives container restarts and runtime changes. For Docker-based deployments, AppArmor prevents container escape even if application vulnerabilities are exploited.
For Linux kernel security auditing, see our kernel security guide. For Linux-level sandboxing frameworks, our landlock and firejail comparison covers alternative approaches.