Case Study
Implementing the NixOS STIG in a Regulated Environment
A regulated organization made a US DoD hardening baseline part of its NixOS releases. Those releases now ship with compliance evidence, and tests show that key rules both pass and work.
- Industry
- Regulated environment
- Service
- Secure Software Supply Chain
- Scope
- All 103 rules of the NixOS STIG
- Stack
- NixOS modules · NixOS integration tests · auditd · PAM · FIPS-capable kernel
- Talks
- Implementing the NixOS STIG 🔗 · Alexander Foremny · NixCon 2026, Kraków
The goal
Our client built and operates secure infrastructure with NixOS in a regulated environment. They chose NixOS years ago in an evaluation we did together. Stakeholders valued NixOS’s declarative nature because audit-related documentation maps more easily to declarative NixOS configs than to Ansible scripts. Every machine is described in code, making it easy to map a line of NixOS config to the regulation it satisfies.
Government auditors expect detailed proof: The client must show that every machine follows a government-grade hardening baseline with a formal description. The client needs to implement the NixOS STIG (Security Technical Implementation Guide), published by DISA (US Department of Defense) in 2024 and revised in 2025 as part of its STIG library. 103 rules cover auditing, cryptography, SSH, kernel, and PAM. Each rule expresses/checks the requirements in NIST SP 800-53. Rules consist of check text, the command an assessor runs, and fix text (which, for NixOS, is usually a line of Nix). Because a failed audit can hold up operations or accreditation, this baseline must hold on every machine and in every release.
Passing != working
At first, this work seems like a plain translation of fix texts into NixOS configuration values. This is not completely wrong, but most of the effort turned out to be elsewhere, as the following examples show: The STIG is young/unpolished, and for some rules, the fix text and check text don’t work well together right away. Several rules require domain knowledge to implement them. Good examples include PAM account lockout and audit daemon configuration. Many text rules are about runtime state like file modes and ownership, which a NixOS configuration doesn’t describe or enforce over a system’s lifetime.

A passing configuration check shows that a setting is present, but does this imply that the setting works at runtime? Passing an audit only at build time is meaningless.

Integration
An audit is evidence for one moment only: The state of a running machine can drift away from its initial configuration. Since the client already treated infrastructure as code, compliance checks became code, too. Each STIG rule is one NixOS module, addressed by its STIG ID. A STIG rule contains:
- the configuration change
- a verifier that runs the check text as a small program on the machine
- rule metadata for the compliance report

The community has already done valuable hardening work:
- nixos-stig-anduril for the same STIG
- Sécurix for the French ANSSI guidelines
When we compared them, none combined all the parts our client needed: single rules that can be switched off, a compliance report, a runtime verifier, and tests of actual security behavior.
We left the check texts exactly as the STIG defines them to stick to the audit-relevant outputs. Where a check alone proves too little, we added checks and behavioral NixOS integration tests.

Findings of the extra tests
Following the STIG to the letter would have produced green checks in places where the machine was not doing what the rule intended, so the examples below show why extra tests matter. Let’s look at examples:
Account locking
Rule ANIX-00-000040 requires locking an account after 3 failed logins. In the NixOS configuration, the fix text’s PAM configuration and the default NixOS password check don’t mix well, so the result is that after 3 failed login attempts, login still works because the default password check comes first in the PAM config. After 3 failed login attempts, login still works because the default password check comes first in the PAM config. Only an integration test catches and rules out such behavior. The rule now uses the NixOS PAM options with an explicit order.

FIPS mode activation
The high-severity rule ANIX-00-001840 requires FIPS 140-validated cryptography.
Even if the fix text adds fips=1 to the kernel command line, this check is worthless if the kernel ignores it at runtime with a message like
Unknown kernel command line parameters "fips=1", will be passed to user space
The default kernel configuration doesn’t enable FIPS mode and ignores the parameter, so the check passes while FIPS is off. This means that the kernel configuration also needs to be checked.

auditd configuration
Multiple rules’ fix texts, such as ANIX-00-000420, write the auditd configuration file directly, although NixOS generates that file from its options. Although the machine would behave correctly at runtime, reports derived from the configuration would still show the old configuration. Setting all values through NixOS options synchronizes report and machine config at runtime.
Firewall rules
The fix text of rule ANIX-00-000010 enables the firewall.
It also requires firewall-panic tools that cut all remote access in an emergency.
The fix text does not assert their installation.
With those tools added, the rule check passes and works as intended.
Luckily, NixOS, the Linux kernel, modules, etc. are fully open source, so these rules and checks were easy to fix.
Result
The client’s NixOS releases now implement all 103 STIG rules, and each release ships with compliance reports as build artifacts. Compliance reports are just a build artifact of releases. Behavioral integration tests with VMs quickly uncover regressions before deployment, which keeps maintenance cycles short.
Because drift may occur after system updates or bad configuration changes, we run verifiers in CI and on deployed machines.
Open source
The implementation is client-only and not public today. We’re working on a release, but it has to clear multiple bureaucratic hurdles.
In the meantime, watch our NixCon 2026 talk!
Value Proposition
- The hardening works, including in places where following the STIG to the letter would not have been enough, and the releases ship with compliance evidence.
- Easy audit generation with every build.
- Drift detection: In the CI and on the deployed machines.
- Porting effort for 103 rules is a one-time investment that pays off for all future deployments.
- In practice, our client’s vision of mapping NixOS configuration lines to regulatory requirements proved feasible: all hardening settings map to their STIG rules.