# Podman Mounted Directory Permission Denied: A SELinux Gotcha


When mounting host directories to Podman containers, you may encounter `Permission denied` even when running as root inside the container. This article explains the root cause—SELinux—and provides the fix.

## The Problem Scenario

I was configuring a Quadlet-managed service with a `.container` file like this:

```ini
[Container]
Entrypoint=/app/entry.sh
Image=docker.io/library/alpine:3.15
Pod=sniproxy.pod
Volume=/home/nite/pod/sniproxy/data/bin:/app:ro
Volume=/home/nite/pod/sniproxy/data/etc:/config:ro

[Service]
Restart=always

[Install]
WantedBy=default.target
```

After configuration, running `systemctl --user daemon-reload` and `systemctl --user start sniproxy.service` resulted in a failed start.

Checking the logs via `journalctl` revealed a `Permission denied` error. To verify, I commented out the Entrypoint, set `Exec=sleep infinity`, restarted the service, then used `podman exec` to enter the container. Running `ls -l /app` also returned `Permission denied`.

I was root inside the container, and traditional file permissions (owner, group, other) should have granted access. Something else was blocking it.

## Root Cause: SELinux

On distributions with SELinux enabled (Fedora, CentOS, RHEL), file access is additionally constrained by SELinux security contexts.

When Podman starts a container, processes inside are assigned an SELinux label, typically `container_t`. Directories created under the host's home directory (e.g., `~/sniproxy/data`) have a default label of `user_home_t`.

SELinux's default policy explicitly forbids processes with the `container_t` label from accessing `user_home_t`-labeled directories. This is a deliberate security measure: it prevents container processes (even if compromised) from reading or tampering with personal files on the host.

The `Permission denied` is not due to traditional permissions, but because SELinux policy blocks `container_t` from accessing `user_home_t`.

## Solution: Modify the SELinux Label

The fix is to have Podman modify the directory's SELinux label when mounting. Append one of these flags to the volume definition:

- `:z`: Changes the directory label to `container_file_t`, a **shared** label that multiple containers can access.
- `:Z`: Creates a **private** label for the directory, accessible only by that container.

For most cases, `:z` is the right choice.

**Before**:

```ini
Volume=/home/nite/pod/sniproxy/data/bin:/app:ro
Volume=/home/nite/pod/sniproxy/data/etc:/config:ro
```

**After**:

```ini
Volume=/home/nite/pod/sniproxy/data/bin:/app:ro,z
Volume=/home/nite/pod/sniproxy/data/etc:/config:ro,z
```

After editing the Quadlet file, run:

```bash
systemctl --user daemon-reload
systemctl --user restart sniproxy.service
```

Now `podman exec` into the container, and `ls -l /app` works as expected.


---

> Author: Nite  
> URL: https://www.nite07.com/en/posts/podman-selinux/  

