systemd Service Hardening: What the Exposure Score Does Not Tell You
Run systemd-analyze security on a typical machine and you get a table of services with a number beside each one. It is tempting to read that number as a verdict. The manual page says, in unusually direct terms, that it is not.
What the command actually measures
systemd-analyze security inspects the security and sandboxing settings of service units. Given a unit name it shows a detailed analysis; given none, it inspects all currently loaded long-running service units and prints a terse table.
It assigns each relevant setting a numeric exposure level, then calculates an overall value for the unit. The documentation describes this as “an estimation in the range 0.0…10.0 indicating how exposed a service is security-wise”. High values mean very little sandboxing has been applied. Low values mean tight sandboxing and strong restrictions.
So far this reads like a scanner. The important part is the disclaimer that follows.
The three limits the manual states outright
It only sees what systemd itself implements. The documentation is explicit: this “only analyzes the per-service security features systemd itself implements”, which means “any additional security mechanisms applied by the service code itself are not accounted for”. A service that drops privileges internally, chroots itself or applies its own seccomp filter gets no credit whatsoever.
A high score does not mean vulnerable. This sentence deserves quoting in full, because it is the one people skip: a high exposure level “neither means that there is no effective sandboxing applied by the service code itself, nor that the service is actually vulnerable to remote or local attacks”. What it does indicate is that the service “might benefit from additional settings”.
Individual settings can be undone. The manual warns that many sandboxing settings “individually can be circumvented” unless combined with others. It gives a concrete case: a service that keeps the privilege to establish or undo mount points can unwind many of the other sandboxing options from inside its own code. The tool accounts for some of these relationships, but the documentation says plainly that it does not account for all of them.

Why “combined” is the operative word
The mount-point example is worth sitting with, because it changes how you should read your own results.
If a unit can manipulate mount points, then restrictions expressed as filesystem visibility can potentially be reversed by the service itself. The restriction is still declared, and the score still counts it, but its practical value depends on another setting being present alongside it.
This is why a checklist approach produces disappointing results. Picking the three directives that lower the score fastest can leave a configuration that scores well and holds poorly. The documentation’s own conclusion is that each service should use “the most comprehensive and strict sandboxing and security settings possible”, not a selection of them.
How to use the score without misreading it
A workable reading, consistent with what the manual claims for the tool:
Treat it as an inventory, not an audit. It tells you which systemd-level protections are absent. That is genuinely useful and it is cheap to obtain. It does not tell you whether a service is safe.
Compare against yourself over time. The most reliable use is regression detection: a unit whose exposure level rises after a package update or a configuration change is worth investigating. That comparison is meaningful even though the absolute number is not a verdict.
Do not rank third-party services by score. Two services with the same number can have very different real-world exposure, because the tool cannot see the sandboxing one of them does internally. Ranking them by the score would reward the one that declares more and punish the one that does more.
Start with the units that are actually reachable. A network-facing service with a high exposure level is a different proposition from a local timer with the same number. The score does not know which is which, and you do.
The honest summary
systemd-analyze security is a good tool that describes itself accurately, which is rarer than it should be. It measures the systemd-level sandboxing you have declared, on a 0 to 10 scale, and it says explicitly that a high number is not a vulnerability finding and a low number is not a clean bill of health.
Use it to find missing protections and to catch regressions. Combine settings rather than picking the cheapest ones, since the manual warns that isolated restrictions can be undone from inside the service. And keep in mind that the number describes your configuration, not your attack surface.
For the layer underneath this one, our Linux hardening guide covers kernel parameters, sysctl and mandatory access control.
The description of the command, the 0.0 to 10.0 exposure range, the three stated limits and the mount-point example are taken from the systemd-analyze manual page as shipped with systemd 255. Wording and behaviour can change between systemd releases; check the manual for the version you run. This article does not include a sample of command output because the environment used to write it does not run systemd as PID 1, and inventing one would misrepresent a real result.