Managing File Permissions in Rootless Podman with User Namespaces
Learn how to solve file permission conflicts in rootless Podman using 'podman unshare' and user namespace mapping to manage subordinate UIDs.
22 Sept 2025, 09:18 UTC

The Rootless Permission Gap
When running Podman in rootless mode, a fundamental disconnect occurs between how the host sees a file and how the container sees it. A file owned by the root user inside a container is actually owned by your unprivileged user on the host. However, files owned by other IDs inside the container (like a mysql or nginx user) map to a range of subordinate UIDs that your host user does not naturally "own" in a standard shell session.
The takeaway: To modify files that belong to non-root container users from the host, you cannot use standard sudo or chown. You must use podman unshare to enter the user namespace where those subordinate mappings are active.
How User Namespace Mapping Works
Podman leverages User Namespaces (userns) to map a range of UIDs. This is configured in /etc/subuid and /etc/subgid. A typical entry looks like this:
username:100000:65536
This tells the kernel that the user username is allowed to use 65,536 IDs starting from 100,000. Inside the container, UID 0 (root) maps to your host UID, and UID 1 maps to host UID 100,000.
Practical Example: Fixing Volume Permissions
Imagine you are running a PostgreSQL container. PostgreSQL typically runs as UID 999 inside the container. If you mount a host directory as a volume, the container may fail to start because it cannot write to that directory.
Scenario: You have a folder ~/pg_data that you want to mount. On the host, it is owned by your user, but the container's postgres user (UID 999) needs access.
Step 1: Verify the mapping
Run this on your host to see your allocated subordinate IDs:
cat /etc/subuid
Step 2: Use podman unshare
Instead of using sudo chown (which would make the file owned by the host root), use podman unshare. This command executes a process in the same user namespace the containers use.
# Run this as your normal unprivileged user
# This changes the ownership of the folder to the ID that maps to 999 inside the container
podman unshare chown -R 999:999 ~/pg_data
Step 3: Launch the container
Now, launch the container using the volume mount:
podman run -d --name db -v ~/pg_data:/var/lib/postgresql/data:Z postgres
Note: The :Z flag tells Podman to relabel the files for SELinux if applicable.
Limitations and Common Pitfalls
Privileged Port Binding
Rootless containers cannot bind to ports below 1024 because the host kernel restricts these to the real root user. If you need to run a web server on port 80, you have two options:
- Map the container port 80 to a host port above 1024 (e.g.,
-p 8080:80). - Modify the kernel parameter to allow unprivileged users to bind to lower ports:
sudo sysctl net.ipv4.ip_unprivileged_port_start=80.
The Storage Driver Overhead
Because unprivileged users cannot perform standard mounts, Podman often uses fuse-overlayfs. While this enables rootless operation, it can introduce a slight performance penalty in I/O-heavy workloads compared to the kernel-level overlayfs used by root-full Podman.
Network Performance
Rootless Podman uses slirp4netns or pasta for networking. These tools emulate a network stack in user space. For most applications, this is negligible, but for high-throughput networking applications, you may see increased CPU usage and latency compared to the standard bridge networking used by root users.
Verification and Diagnostics
To confirm your environment is correctly configured for rootless operation, run the following checks:
| Check | Command | Expected Result |
|---|---|---|
| Rootless Status | podman info | grep rootless |
rootless: true |
| Internal Identity | podman run --rm alpine id |
uid=0(root) gid=0(root) |
| External Identity | ps -ef | grep podman |
Process owned by your non-root username |
Rollback Procedure
If you used podman unshare chown and need to return the files to your host user's ownership, run:
# Replace 'username' with your actual host username
sudo chown -R username:username ~/pg_data0 replies
A thoughtful contribution can make all the difference. Be the first to share one.