Safeguard
Security Guides•

SELinux or AppArmor: which mandatory access control for a server

Choose SELinux or AppArmor mainly by distribution, then by how much policy work you can own. How each works, its modes and a decision rule from the docs.

Safeguard Security Team
4 min read

Pick the mandatory access control system your distribution ships and supports: for example SELinux on Red Hat family systems and AppArmor on Ubuntu. Both confine programs beyond normal file permissions. The best one is the one you leave in enforcing mode and keep maintained, so choose by support and team skill first.

What each one does

Both add a second layer of rules on top of user and group permissions, so a compromised process is limited to what policy allows even if it runs as root.

AppArmor. The AppArmor manual describes it as a kernel enhancement to confine programs to a limited set of resources, with a security model that binds access control attributes to programs rather than to users. Profiles are loaded into the kernel, usually through the apparmor.service unit, and are traditionally stored under /etc/apparmor.d/, named after the program path. A profile applies at exec time. A process already running unconfined cannot be confined later. The manual adds that AppArmor restricts privileged operations even for root, for example a confined process cannot call ptrace, reboot or init_module.

SELinux. The Red Hat documentation describes the policy as applied by labels on files and processes, with enforcing and permissive modes plus a disabled state. SELinux depends on correct labels on every file system object, which is why it relabels after being re-enabled.

Modes, side by side

AppArmorSELinux
EnforceProfile enforced and violations reportedPolicy enforced, access denied
LearnComplain mode: allows and logsPermissive mode: logs only
OffPer profile or unloadedDisabled: no policy loaded

The AppArmor manual warns that complain mode provides no security, only auditing, and should not be used in a hostile environment. Permissive mode on SELinux has the same property. Details are in AppArmor complain or enforce and SELinux permissive vs disabled.

A decision rule

  1. Use what your distribution supports. Vendor policy, documentation and bug reports assume it. Switching systems on a distribution that does not ship the other is a lot of work.
  2. Count your custom software. Packaged software usually comes with policy. Internal apps need a profile or module that someone writes and maintains.
  3. Check team skill. A team that knows how to read denials and fix labels or profiles gets value. A team that disables it at the first outage gets none.
  4. Plan for containers. If you run containers, see which of seccomp, AppArmor or SELinux fits Kubernetes.
  5. Decide the exception process. When a service breaks, the path should be permissive for that one domain or profile, fix, enforce again, not disable everything.

Common mistakes

  • Leaving the system in permissive or complain mode permanently.
  • Writing a wide allow rule to silence a denial without reading it.
  • Skipping the check after upgrades, since policy and profiles change with packages.
  • Treating it as a substitute for patching. It limits damage, it does not remove the bug.

Safeguard offers asset discovery, compliance evidence automation and policies, gates and guardrails, and there is a free scan at gold.safeguard.sh/scan.

Quick check

Can I run SELinux and AppArmor together on one host?

Not in the usual setup. Distributions normally enable one primary system, so use the one your distribution supports.

Is complain or permissive mode a safe default?

No. Both log without blocking. Use them briefly for debugging, then return to enforcing.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.