TemporaryFileSystem and BindPaths create two different views of the same host
TemporaryFileSystem and BindPaths create two different views of the same host
A systemd service can begin with an empty temporary view of a directory and then receive selected files or directories through bind mounts. TemporaryFileSystem= and BindPaths= are often configured together to hide sensitive host content while preserving one required path. The result is useful, but the mount sequence and source path need to be understood.
Replace first, bind second
TemporaryFileSystem=/var:ro hides the host's /var inside the service's mount namespace and replaces it with a read-only tmpfs. A later BindReadOnlyPaths=/var/lib/systemd can make a specific subtree visible again.
The service does not see the original /var tree merely because the bind source came from the host. The kernel mounts the requested source into the service namespace over the temporary mount. Paths not explicitly bound remain absent or empty.
This pattern is more flexible than InaccessiblePaths= when a service needs nested access. The systemd manual notes that bind and writable-path exceptions cannot be nested inside an inaccessible path, but they can be layered after a temporary filesystem.
Read-only is not confidentiality
A read-only bind mount prevents writes through the mounted path. It does not select only safe files. If the source directory contains credentials, tokens, or private keys, the service can read them. File ownership and mode checks still apply in the new namespace, but the mount itself does not know which files are appropriate.
Treat every bind source as an exposure decision. Enumerate the directory's contents at deployment time and after package updates. A service account may be denied access by ordinary filesystem permissions, while another service account with broader group membership can read the same bind mount. The unit's security review must include that identity mapping.
Mount propagation changes later
systemd creates a private mount namespace for these settings. Host mounts created later can propagate into the service namespace, while mounts created by the service do not propagate back to the host. The systemd manual also warns that a writable host mount can appear writable inside the service even when it propagates below a path marked read-only.
That warning means a successful mount inspection at startup is not the whole test. Compare the mount view during the service's normal workload. Long-lived services may receive a new data volume, a container runtime mount, or an administrator's bind mount after startup.
The complete control also needs capability restrictions. A privileged process can undo namespace mapping, or perform mount operations that expose another path. Use CapabilityBoundingSet= and a mount system call filter when the service does not need those operations.
A reviewable unit
The following pattern narrows the view of /var while keeping one read-only dependency:
[Service] User=app TemporaryFileSystem=/var:ro BindReadOnlyPaths=/var/lib/systemd PrivateTmp=yes ProtectSystem=strict ReadWritePaths=/var/lib/example CapabilityBoundingSet= SystemCallFilter=~@mount The ReadWritePaths= entry must be reachable in the service's resulting mount namespace. If it is below a temporary mount that has no corresponding bind, the service cannot write there. That failure can be difficult to diagnose because the directory name is still recognizable and the unit file looks correct.
Run systemctl cat and systemctl show before testing the application. systemctl cat shows the merged unit, while systemctl show exposes the effective properties. Neither command proves the mount source contains the intended files. Use an unprivileged test process inside the same sandbox to list the paths and attempt a harmless read.
Keep the source inventory
Maintain a small table for each service: temporary mount, bind source, mount mode, reason for access, owner, and update process. This makes package upgrades and incident reviews tractable. If a base image adds a file to a bound directory, the service sees it on the next start.
At incident response time, collect the unit's effective properties and the running mount namespace. Losing the namespace after a restart destroys evidence. The host still has its original /var, but the service's view, including hidden paths and temporary files, may not be reproducible.