Podman
Deploy the LinuxGuard agent under Podman — rootless vs rootful trade-offs, systemd quadlet integration, Docker-equivalent commands.
Podman is a daemonless container engine that runs containers as ordinary user processes. The LinuxGuard agent runs under Podman with two distinct trade-offs: rootful (full eBPF telemetry, ergonomically equivalent to Docker) or rootless (least-privilege execution, restricted telemetry surface). This page documents both shapes plus systemd quadlet integration for hosts where the agent should be a system service.
Important: Rootless Podman cannot grant
CAP_BPF+CAP_PERFMONto the container because user namespaces do not propagate the host's eBPF capabilities to the container's PID-1. Rootless agents run inDEGRADED_PROBES_PARTIALmode — the agent process starts and produces non-eBPF telemetry, but no behavioral, auth, or file-monitor events are produced. Use rootful Podman when full telemetry coverage is required.
When to use Podman
Hosts where Docker daemon access is restricted (locked-down workstations, hardened servers, multi-tenant build hosts). Podman's daemonless model fits the security posture.
systemd-native deployments where the agent should be a
--useror system service managed bysystemctl. The quadlet integration is canonical for this shape.RHEL / Fedora / SUSE hosts where Podman is the supported container engine and Docker is not packaged.
If your host runs Docker, the docker-compose shape (docker-compose deployment) is simpler — Podman's podman-compose is API-compatible but has fewer eyes on it.
Rootless vs rootful trade-offs
eBPF probes
Yes (full)
No — user namespaces drop the agent's caps; loader degrades to DEGRADED_PROBES_PARTIAL
Behavioral telemetry
Yes
No
Auth events
Yes
No
File monitor
Yes
No
Configuration management
Yes
Yes
Package inventory
Yes
Yes
Syslog forwarding
Yes
Yes
support-bundle collect
Yes
Yes
Privilege required to start
sudo podman or member of the podman group
Any user; no privilege elevation
Host filesystem visibility
Full
User-namespace remapped
pid=host
Available
Available but limited to the user's own processes
Image storage location
/var/lib/containers/
~/.local/share/containers/
Choose rootful when behavioral telemetry coverage is required (the standard case for a security agent).
Choose rootless when the host's security policy forbids daemonless privileged containers AND the agent's role is limited to configuration management, package inventory, or syslog forwarding (a narrow surface).
Rootful Podman
The rootful shape is ergonomically equivalent to a Docker run with the same flags. The only difference is the engine binary.
Minimal invocation
The flags match the Docker equivalent line-for-line; see docker-compose deployment for the rationale on each.
Differences from Docker
sudoprefix — rootful Podman requires eithersudoor membership in thepodmangroup. Thepodmangroup has no default member; add users explicitly viausermod -aG podman <user>.No daemon to start — Podman is daemonless. There is no
systemctl start podmanfor the rootful case (thepodman.socketunit is used only for the Docker-compatibility API).Image storage — rootful Podman stores images in
/var/lib/containers/. Free space requirements match Docker's/var/lib/docker/.SELinux labeling — on RHEL/CentOS/Fedora hosts with SELinux enforcing, Podman applies the
container_ttype to the container's processes. Host-path mounts may require:zor:Zsuffix for SELinux relabeling — see § SELinux considerations.
Rootless Podman
Rootless Podman runs the container in a user namespace owned by the invoking user. Capabilities granted at --cap-add time are scoped to that namespace, not the host's. The agent's eBPF loader detects this at startup and degrades to DEGRADED_PROBES_PARTIAL mode.
Minimal invocation (rootless)
Notes on what is OMITTED from the rootless invocation:
No
--cap-addflags — the capabilities are scoped to the user namespace and have no effect on the host eBPF subsystem. The agent will log a startup warning about degraded mode.No
--pid=host— rootless Podman cannot grant host PID visibility; the agent sees only the user's own processes.No tracefs bind-mount — without
CAP_BPFthe agent does not attempt probe attach.No host
/procmount.
Verifying degraded mode
After the agent starts, the log should contain a clear degradation marker:
If your security policy permits, switch to the rootful shape to recover the eBPF telemetry surface. Otherwise, document the rootless deployment as a known coverage gap.
systemd quadlet integration
A quadlet is a systemd unit file that describes a Podman container in a declarative, systemd-native way. Quadlets are preferred over podman generate systemd (which generates verbose units that mix Podman state into systemd state) because they are simpler, idempotent, and version-controlled like any other systemd unit.
Rootful quadlet
Place the following file at /etc/containers/systemd/linuxguard-agent.container:
Generate the systemd unit and enable it:
The EnvironmentFile=/etc/linuxguard/enroll.env references a file with the token + tenant ID:
Restrict permissions on the env file:
Only root and the linuxguard group can read the env file. systemd reads it as root when the service starts; the value is then injected into the container's environ block via Podman.
Rootless quadlet
Place the file at ~/.config/containers/systemd/linuxguard-agent.container (note the user-scoped path):
Enable as a user service:
The rootless quadlet inherits the same degradation properties as the rootless podman run invocation — see § Rootless Podman.
Docker-equivalent commands
For operators familiar with Docker, the table below maps common workflows to their Podman equivalents. The agent's behavior is identical under either engine.
docker run ...
podman run ...
Identical syntax. Rootful Podman requires sudo.
docker compose up -d
podman-compose up -d
podman-compose is a Python wrapper; install with pip install podman-compose or via distro package.
docker ps
podman ps
Identical.
docker logs -f linuxguard-agent
podman logs -f linuxguard-agent
Identical.
docker exec linuxguard-agent <cmd>
podman exec linuxguard-agent <cmd>
Identical. The distroless image has no shell; pass a specific command.
docker stop linuxguard-agent
podman stop linuxguard-agent
Identical. Sends SIGTERM; agent exits 143.
docker pull <image>
podman pull <image>
Identical.
docker login <registry>
podman login <registry>
Identical. Credentials stored in ~/.config/containers/auth.json.
docker inspect <ctr>
podman inspect <ctr>
Identical output structure.
docker system df
podman system df
Identical.
SELinux considerations
On RHEL / CentOS / Fedora / Rocky Linux hosts with SELinux enforcing, Podman applies the container_t type to processes inside the container. Host-path mounts must be relabeled or the agent's reads from /sys/kernel/tracing are denied with avc: denied.
Two options:
Option 1: :z / :Z mount suffix
:z / :Z mount suffixAppend :z (shared label) or :Z (private label) to the -v flag value. This is the simplest approach for single-host deployments:
:z relabels the host directory so the container can read it AND other containers can read it (shared). :Z relabels for exclusive access by this one container. For /sys/kernel/tracing (a kernel pseudo-filesystem, not real disk), :z is appropriate.
Option 2: Set the agent's SELinux profile at host level
Install the SELinux policy that ships with the agent's packaging tree, then label the agent's process with the policy's domain:
This is the production path. It avoids the :z / :Z relabel side effect on host directories.
Verifying SELinux is not blocking
If recent AVC denials appear, set SELinux to permissive temporarily to confirm the agent works in the absence of policy enforcement:
Then apply Option 1 or Option 2 to allow the agent under enforcing mode.
Security context
The rootful Podman security context is equivalent to the Kubernetes DaemonSet shape — see Kubernetes DaemonSet § Line-by-line rationale for the per-capability rationale. The rootless Podman security context inherits the user namespace's degradation as documented in § Rootless vs rootful trade-offs.
Common to both: read_only filesystem, tmpfs for the TLS cache, no privilege escalation needed (file caps baked into the binary), nonroot user (UID 65532 inside the container, remapped to a high UID range in the rootless case).
Host paths
Identical to the Kubernetes DaemonSet host-path requirements for the rootful case — see Kubernetes DaemonSet § Host paths. The rootless case omits the host-path mounts entirely because the user namespace cannot productively use them.
Security Note: For SELinux-enforcing hosts, mount each host path with
:z(or apply the SELinux module per Option 2 above). For the rootless case, do not mount host paths — the user namespace cannot use them.
Pod Security Standard compatibility
PSS is a Kubernetes concept; it does not apply to Podman. The Podman equivalent is the combination of --cap-add / --cap-drop, --security-opt, --read-only, --tmpfs, --pid, and the rootful-vs-rootless distinction. The rootful Podman shape corresponds to PSS privileged (because of --pid=host and the added capabilities); the rootless shape has no Kubernetes analogue.
RBAC
RBAC is a Kubernetes concept; it does not apply to Podman. The Podman equivalent is filesystem access control on the Podman binary and the user namespace:
Rootful — access is controlled by
sudopolicy orpodmangroup membership. Restrict membership to trusted users.Rootless — access is per-user. The Podman binary itself is unprivileged; the user namespace determines what the container can see.
For the quadlet integration, systemd's unit-file permissions (/etc/containers/systemd/ for rootful, ~/.config/containers/systemd/ for rootless) control who can modify the agent's deployment manifest.
Verification
After starting the agent (via podman run, podman-compose, or the quadlet service):
A healthy rootful agent produces a heartbeat log line within 20 seconds. A degraded rootless agent produces the degradation warning, then a heartbeat with the reduced telemetry surface.
Next Step: OCI multi-arch manifest →
Related: Container deployment hub | docker-compose deployment | Kubernetes DaemonSet | Distroless image reference | probe CLI reference
Last updated
Was this helpful?