Rootless Podman

Provision a Podman environment for unprivileged, non-local (AD) users on RHEL.

Overview

There are many corners to this envelope:

Local-user Service Account (per AD user)

1. No login shell

To allow for self-provisioning, the AD user must be member of podman-sudoers group, which may be either AD or local.

Admin

sudo install.sh

User(s)

Users must be member of the group declared in the apropos group-scoped sudoers file that allows such access.

  1. Self provision a fully-functional rootless Podman environment

    u0@a0 # unprivileged user
    ☩ sudo podman-provision-nologin.sh
    
  2. Use it to run Podman commands

    u0@a0 # unprivileged user
    ☩ podman run --rm --volume $work:/mnt/home alpine sh -c '
        echo $(whoami)@$(hostname -f)
        umask 002
        rm -f /mnt/home/test-write-access-*
        ls -hl /mnt/home
        touch /mnt/home/test-write-access-$(date -u '+%Y-%m-%dT%H.%M.%SZ')
        ls -hl /mnt/home
    '
    root@65f76044ffcb
    total 0
    total 0
    -rw-rw-r--    1 root     root     0 ... test-write-access-2025-05-11T19.08.32Z
    
    ☩ ls /work/podman/home/u0
    total 0
    -rw-rw-r--. 1 podman-u0 podman-u0 0 ... test-write-access-2025-05-11T19.08.32Z
    
    ☩ ls -n /work/podman/home/u0
    total 0
    -rw-rw-r--. 1 50004 50004 0         ... test-write-access-2025-05-11T19.08.32Z
    
    • Podman rootless : The root user of container is not root at host, but rather maps to host user (podman-u0) who ran the command.

2. Login shell

TODO

❌ Common Service Account

A common service account for multiple developers running rootless Podman is technically possible, but collisions and subtle failures are highly likely, and increase rapidly with team size and intensity of usage.


⚠️ Key Problems with a Shared Podman Account

Rootless Podman heavily relies on per-user namespaces, cgroups, and runtime directories that are not designed for concurrent use by multiple interactive users under a shared UID.

Here’s a breakdown of what can and will go wrong:


1. Shared XDG_RUNTIME_DIR

By default, rootless Podman uses:

$XDG_RUNTIME_DIR = /run/user/$(id -u)

In a shared account, everyone has the same UID, so they share /run/user/1001, for example.

Collision symptoms:


2. Volume, Image, and Container Name Clashes

All container objects are stored in a single namespace (under that user’s $HOME/.local/share/containers or /var/tmp/containers/...).

Collision symptoms:


3. File Ownership and Permissions

Files written by Podman in shared directories (volumes, mounts, container data) are owned by the service account, not the real invoking user.

This means:


4. Trouble with loginctl / lingering

Even if loginctl enable-linger podmaners is active, only one instance of the user service is assumed to be running.

If multiple users:

You'll encounter unpredictable behavior or crashes.


5. Security and Auditing


🛑 Bottom Line: Shared Account Not Viable at Scale

For one-off automation or tightly scripted CI/CD tasks, a shared rootless Podman account might work.

But for interactive, multi-user development, it's fragile, unsafe, and increasingly error-prone.


✅ Recommended Alternative for ~12 Developer Team

Provision a dedicated Podman service account per developer, either:

And provision:


su vs sudo -u

Shell Requirements: su vs sudo -u

Command Requires Login Shell? Works with nologin? Best For
su - $name Yes (/bin/bash) ❌ No (nologin fails) Interactive sessions
sudo -u $name No ✅ Yes (ignores shell) Service accounts

Where $name is that of the Podman (service) account common to all users.


Key Differences

1. su (Switch User)

2. sudo -u (Run as User)


Why This Matters for Podman Service Accounts


Best Practices

  1. Always use sudo -u for service accounts:

    sudo -u podmaners podman [command]
    
  2. Never change nologin to bash:

    # ❌ Dangerous (don't do this!)
    sudo usermod -s /bin/bash podmaners
    
  3. If you need debugging:

    # Temporary shell (avoid unless necessary)
    sudo -u podmaners bash -c 'whoami && podman info'
    

Example: Secure Podman Setup

# Create service account (no shell, no home dir)
sudo useradd -r -s /sbin/nologin -d /var/empty podmaners

# Verify
sudo -u podmaners podman info  # ✅ Works
su - podmaners                 # ❌ Fails (as intended)

Final Answer

Use sudo -u podmaners – it bypasses shell checks and is secure. ❌ Avoid su for service accounts – it requires a shell and weakens security.

Need to debug a nologin account? Use:

sudo -u podmaners bash -c '[commands]'  # Temporary exception

Further Comparison

🔹 Scheme A: sudo -u podmaners podman

Users invoke Podman indirectly:


🔹 Scheme B: ssh podmaners@localhost

Users invoke Podman interactively:


🔒 Security Comparison

Feature Scheme A: sudo -u Scheme B: ssh localhost
Access Surface Limited to podman command via sudoers Full interactive shell if not further restricted
User Auditing Logs sudo invocations (audit trail) Harder to attribute actions to specific users without per-key command= restriction
Privilege Escalation Risk Low, if sudoers is tight Higher — any bug or misconfigured shell environment might be exploitable
Isolation Between Users Weak — shared user means shared state (UID, XDG_RUNTIME_DIR, containers) Same weakness unless separate users are used
User Convenience Scriptable but less flexible Fully interactive; user can run shell + Podman tooling
SELinux Compatibility Controlled by calling user (via sudo) Depends on SSH session context; easier to misconfigure SELinux domains
Revocation Simple — remove sudoers line Must remove user’s SSH key manually

🔐 Verdict: Scheme A is more secure by default

Why:


🛠️ If You Must Use Scheme B (SSH):

and use ForceCommand in sshd_config:

```bash
Match User podmaners
  ForceCommand /usr/bin/podman
  PermitTTY no
  AllowTcpForwarding no
```