AppArmor and SELinux on openSUSE: podman gotchas

Find out which security module you run, fix the usual container volume denials, and read the log instead of switching it off.

Part 9 of 10 in openSUSE home server setup. Last updated

In short: New Tumbleweed installs use SELinux by default since February 2025; existing installs keep AppArmor, and the installer can still pick AppArmor. cat /sys/kernel/security/lsm tells you which. On SELinux, a bind-mounted folder needs a label: add :Z to the volume (Volume=%h/appdata:/data:Z) for a folder only that container uses, :z for a folder several containers share, and never relabel your whole home or a system directory. Read denials with ausearch or the journal, and test with setenforce 0 only briefly. Whether podman confines a container at all depends on the host module, the policy packages and rootless versus rootful: check with podman info and /proc/self/attr/current inside a container.

Which one do I have?

In February 2025 Tumbleweed made SELinux in enforcing mode the default for new installations; existing installations keep AppArmor, and the installer still lets you pick AppArmor (openSUSE News: Tumbleweed Adopts SELinux as Default). So two Tumbleweed machines can differ, and many forum answers are older than the switch. Check your own system before you follow one:

cat /sys/kernel/security/lsm               # contains selinux or apparmor
getenforce                                 # SELinux: Enforcing, Permissive or Disabled
sudo aa-status                             # AppArmor: loaded profiles (package apparmor-utils)
The host kernel decides, whatever distribution the image comes from.

A Tumbleweed laptop that runs AppArmor, and a Fedora container running on it:

$ cat /sys/kernel/security/lsm
lockdown,capability,landlock,yama,apparmor,bpf,ima,evm
# inside the Fedora 44 container
$ ls /sys/fs/selinux >/dev/null 2>&1 && echo selinuxfs present || echo 'no selinuxfs: host kernel runs AppArmor'
no selinuxfs: host kernel runs AppArmor

Real output on openSUSE Tumbleweed host and a Fedora 44 container (distrobox), 2026-09-28; user and host names and addresses redacted.

SELinux: volumes and :Z

SELinux gives every file a label, and containers may only touch files labelled for containers. A folder you created in your home has a home label, so the container gets "permission denied" even though the Unix permissions are fine. The fix is a volume option:

[Container]
Volume=%h/appdata/whoami:/data:Z           # private: only this container uses it
Volume=%h/media:/media:z                   # shared: several containers use it
  • :Z relabels the folder for this one container. Another container cannot use it any more.
  • :z relabels it for all containers to share.
  • %h is the user's home directory, filled in by systemd.
ls -Z ~/appdata                            # container_file_t after a :Z mount

Named podman volumes (Volume=whoami-data:/data) are labelled correctly from the start; only bind mounts of existing folders need the option.

SELinux: reading denials

Denials are logged as AVC messages. Reading them needs root:

sudo ausearch -m AVC -ts recent            # when auditd runs (package audit)
sudo journalctl -b -g avc                  # otherwise, from the journal
sudo setenforce 0                          # permissive: log but allow, for a quick test
sudo setenforce 1                          # and back to enforcing, right away

If the problem disappears in permissive mode, SELinux is the cause: fix the label and go back to enforcing. setenforce does not survive a reboot, which is a feature here. On a Cockpit server, the SELinux page (package cockpit-selinux) lists the same denials with suggested fixes. The journalctl command builder helps narrow the journal to one boot or time window.

AppArmor and podman

Whether a container is confined at all depends on your setup: which module the host runs, the policy packages installed (container-selinux for SELinux; podman's AppArmor profile is called container-default, set by apparmor_profile in containers.conf(5)), and whether podman runs rootless or as root. Do not assume; check it on your own machine. On this Tumbleweed laptop, with AppArmor active in the kernel and the parser installed, rootless podman reports AppArmor as off and the container process runs unconfined (rootful podman was not tested here, it needs root):

$ cat /sys/module/apparmor/parameters/enabled
Y
$ podman info --format 'apparmor={{.Host.Security.AppArmorEnabled}} selinux={{.Host.Security.SELinuxEnabled}}'
apparmor=false selinux=false
$ podman run --rm registry.fedoraproject.org/fedora:latest cat /proc/self/attr/current
unconfined

Real output on openSUSE Tumbleweed, rootless podman 6.0.2, 2026-09-28; user and host names and addresses redacted.

Run the same three commands on your server. unconfined means AppArmor is not what blocks that container; a profile name followed by (enforce) means it is confined. Where a profile applies, it restricts things like mounting inside the container, not reading your bind mounts, so everyday services seldom hit it. When one does, the denial is in the kernel log:

sudo journalctl -k -g 'apparmor="DENIED"'

For a container that genuinely needs more (rare for home services), test with PodmanArgs=--security-opt apparmor=unconfined in the quadlet, and keep it only if you understand why that container needs it. Plain permission errors on an AppArmor system are usually Unix permissions or user namespace mapping; see the rootless podman guide and the file permissions guide.

Common mistakes

:Z on your home directory or a system folder

Volume=%h:/home:Z relabels your entire home for one container, and SSH or your login may stop working. Only relabel folders that exist for containers. To repair a mislabelled home, sudo restorecon -Rv /home/apps resets the default labels.

:Z on a folder two containers share

The second container to start takes the label away from the first. Use :z for shared folders.

Setting SELINUX=disabled in /etc/selinux/config

It works in the sense that the errors stop, and turning it back on later means a full relabel. Fix the label instead; it is almost always one volume option.

Frequently asked questions

Should I just disable SELinux?

No. It is the layer that stops a compromised container from reading the rest of the system. Almost every podman problem it causes is a missing volume label, fixed with :Z or :z. Use setenforce 0 for a minute to confirm SELinux is the cause, then turn it back on with setenforce 1 and fix the label.

Does :Z do anything on an AppArmor system?

No, podman ignores the SELinux relabel options when SELinux is not active. A quadlet with :Z therefore works on both, which makes it a good default.

Can I switch an existing install from AppArmor to SELinux?

It is possible, but it touches the boot parameters and relabels the whole file system. On a home server, the calm path is to keep what the install has and choose SELinux at the next reinstall.