nix-mineral: NixOS hardening as a module with presets
Conveniently and reasonably harden NixOS.
At a glance
- What is it?
- nix-mineral is a NixOS module that turns a list of hardening settings, sysctl values, kernel parameters, mount options and a module blacklist into a declarative system configuration, with presets for compatibility and performance that override individual settings. It is explicitly alpha software, and its documentation separates what it does, what it omits and what it refuses to do.
- Who is it for?
- Adopt nix-mineral if you run NixOS and want hardening applied declaratively so it survives rebuilds, and you are prepared to read each setting before you enable it rather than trusting a default posture. Do not adopt it on a machine you cannot reinstall easily without reading the caveats, because the project warns in terms that loss of data or functionality may occur on non-fixed releases.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Nix, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A hardening module for a system that is rebuilt constantly
nix-mineral is a NixOS module for convenient system hardening. The name has a small piece of history worth repeating, because it is the kind of detail that tells you the project is run by someone who cares about wording. Rather than being named after a mineral, it is named after the word mineral.
The reason a NixOS module is the right shape for this is specific to NixOS. A hardened Linux system is a pile of sysctl values, kernel parameters, mount options, a list of modules to refuse to load, and a few service configurations. On a conventional distribution you set those once with a script and then they rot, because the next upgrade or reinstall does not remember them. On NixOS the configuration is the system, so hardening is just another set of options in the same file, and it is rebuilt along with everything else.
That is the actual value proposition, and it is a stronger one than the feature list suggests. Hardening advice ages badly, and a declarative module lets you upgrade the hardening and the system together, or hold the hardening still while you move the system forward.
The project is Nix, licensed GPL-3.0, and the last push was on 2026-10-18. The releases are all alphas, v0.4.0-alpha from 2026-08-03, v0.3.4-alpha from 2026-07-29 and v0.3.3-alpha from 2026-07-21, and the readme states plainly that nix-mineral is alpha software, that loss of data or functionality may occur especially on non-fixed releases, and that user cooperation in debugging is expected.
That warning is unusually direct for a project of this kind, and it is the first thing to weigh.
What the module actually changes
The readme says a full rundown of features is best obtained by reading the individual submodules for every option nix-mineral offers, and then names some notable ones.
Filesystem hardening uses both systemd-tmpfiles and mount options, which is the belt and braces approach: tmpfiles handles the per-service temporary file rules, and mount options handle the filesystem mount behaviour, and doing only one of them leaves gaps that the other was covering.
Kernel hardening is extensive and done through sysctl and boot parameters. The sysctl side covers the network stack and related kernel behaviour, and the boot parameters cover what can only be set at boot, things like the kernel lockdown mode and module signing. The split matters because the two are set in different places and have different failure characteristics, since a bad boot parameter stops the machine booting while a bad sysctl usually just does the wrong thing.
Network hardening goes through sysctl and through configuration of the relevant services, so it is not only kernel level. Attack surface reduction is an extensive kernel module blacklist, which is the bluntest of the options and the one most likely to break a device driver you did not know you needed.
System entropy hardening is the fifth headline item, and it is the one that most often surprises people who copy hardening guides from years ago, because the advice changed as the hardware and the kernel did.
The repository layout shows the decomposition. There are filesystems, kernel-modules, settings, presets, lib, extras, tests, docs, licenses and the nix-mineral.nix entry point, plus a flake.nix and flake.lock, and a default.nix for the non-flake path. The settings and presets directories are the public surface, since that is where a user changes behaviour.
Presets, priorities and why one setting at a time matters
The configuration model is the most interesting part of the project, and it is the part that a user has to understand before they enable anything.
The readme says it is likely you will need to change some options in order to make your individual hardware and software configuration function as intended, and that presets for doing so are available in the presets directory of the repository. Refer to the individual submodules for more information on what each option does.
The example configuration shows how presets and individual settings interact, and the comment inside it explains the rule: multiple presets can be used, the order of presets matters, the top ones will receive higher priority values, meaning that presets lower in the list are prioritized.
That is a slightly counter-intuitive convention, so it is worth being careful with. In the example, all settings from the compatibility preset have an override priority of 800, while settings from the performance preset have an override priority of 799, so the compatibility preset wins where the two overlap. The link given is the NixOS manual section on option definitions and setting priorities.
The example also shows the shape of a change: the presets are a list of names, and the settings block holds explicit overrides such as system.multilib set to true and network.ip-forwarding set to true, with a commented-out kernel block showing that the individual options are also directly settable, and then a setting applied through the fully qualified name outside the settings block, where nix-mineral.settings.network.tcp-window-scaling is set to false.
The reason to change one setting at a time is the same reason the presets exist. A hardening module applies many changes at once, and when something breaks after a rebuild you need to know which of a hundred changes caused it. Enabling the compatibility preset and then overriding individual settings is the way to keep the blast radius of your own experimentation small.
Two ways to install it, and one of them pins versions for you
There are two installation methods, and the readme explains why one is preferred.
The automatic installation with fetchgit may be used with or without flakes, but the flake specific method in the next section is preferred because it allows version pinning. Since the project uses flake-compat inside it, you can use nix-mineral without needing to have flakes enabled, using fetchGit:
let
nix-mineral = builtins.fetchGit {
url = "https://github.com/cynicsketch/nix-mineral.git";
};
in
{
imports = [
nix-mineral.nixosModules.nix-mineral
];
nix-mineral = {
enable = true;
};
}The flake method is for flake enabled systems, and it is the one that enables automatic updates and version pinning. The input line in the example is commented to explain the options, and the difference between them is the whole point of using flakes here. The main branch URL is updated to the latest commit when you run nix flake update, a specific tag URL follows that tag until you change it, and a specific commit URL follows that until you change it.
There is also a compatibility warning in the example itself: due to major breaking changes, the examples are not compatible with commits or releases prior to 0.2.0a. That is worth noticing, because it means the option names and the settings structure have changed across the 0.x line, so a configuration written against an older alpha will not apply cleanly to a newer one.
The import step is then a two line change in your own module, adding the nixosModules.nix-mineral import and setting enable to true, and the same enable pattern appears in both methods, which is the only option you have to set to turn hardening on at all.
The documentation set, and where the project says it stops
The documentation structure is the best thing about this project, and it is organised around the questions a user actually has.
The website at cynicsketch.github.io/nix-mineral carries all the documentation as well as option information and search, and the readme points there rather than trying to duplicate it. Alongside it are separate pages for the frequently asked questions with solutions to commonly experienced problems with usage, for the caveats of the project, for the scope which details what the project is for, for additional resources listing other projects and information that may be useful but did not fit elsewhere, and for omitted features, which are things that have been intentionally omitted.
That last document is the one to look at first, and it is unusual to find. Most hardening projects list what they do and stay quiet about the rest. A page that says what was left out, and why, is a project telling you where its own edges are, and it is a better guide to the risk than any feature list.
The credits section is also unusually explicit, both about the people and about the borrowing. The project thanks its contributors, and then lists the projects it has borrowed insight and configuration from, with a note that nix-mineral is not endorsed by any of the projects enumerated unless otherwise specified.
The dependency chain is worth reading. Madaidans Insecurities provided the original basis for hardening, which many of the listed projects have themselves derived from. privsec's Desktop Linux Hardening provided additional information and guidance. secureblue contributed the borrowed kernel module blacklist and inspiration for kernel parameter hardening. Kicksecure's security-misc contributed borrowed Bluetooth configuration and the former default module blacklist. Tommy's Linux-Setup-Scripts supplemented the sysctl hardening. GrapheneOS server infrastructure provided optional borrowed chrony configuration. And Xe Iaso's blog provided the original idea to restrict nix to the wheel user.
Two of those deserve a second look, because they are the kind of choice that can break a system. A borrowed module blacklist is a list of kernel modules the machine will refuse to load, and taking one from another project means inheriting the assumptions of a different distribution and a different hardware set. And restricting nix to the wheel user is a permissions decision that changes who can install software on the machine, which is exactly the sort of thing that needs to be read rather than applied.
Editorial conclusion
Adopt nix-mineral if you run NixOS and want hardening applied declaratively so it survives rebuilds, and you are prepared to read each setting before you enable it rather than trusting a default posture. Do not adopt it on a machine you cannot reinstall easily without reading the caveats, because the project warns in terms that loss of data or functionality may occur on non-fixed releases. Before you commit, work through the FAQ and the caveats documents, apply the compatibility preset first, and change one setting at a time so you can attribute a breakage to the setting that caused it.
Frequently asked questions
What is nix-mineral?
It is a NixOS module for convenient system hardening, a set of declarative options covering filesystem hardening through systemd-tmpfiles and mount options, extensive kernel hardening through sysctl and boot parameters, network hardening, a kernel module blacklist for attack surface reduction, and system entropy hardening. The name refers to the word mineral rather than to an actual mineral.
How do I install nix-mineral on NixOS?
Either with builtins.fetchGit in a plain configuration, which works with or without flakes enabled because the project ships flake-compat, or as a flake input, which the readme prefers because it allows version pinning. Then you import nix-mineral.nixosModules.nix-mineral and set nix-mineral.enable to true.
What are the presets in nix-mineral for?
They provide ready made sets of settings for cases such as compatibility and performance, and the order matters because presets lower in the list are prioritised through higher override priority values. Individual settings can then be overridden outside the settings block, which is how you keep the blast radius of an experiment small.
Is nix-mineral safe to use on a production machine?
The readme states it is alpha software, that loss of data or functionality may occur especially on non-fixed releases, and that user cooperation in debugging is expected. The documentation includes a caveats page and a page of intentionally omitted features, and the examples note that configurations are not compatible with commits or releases prior to 0.2.0a.
Where did the hardening configuration in nix-mineral come from?
The credits list the sources it borrowed from, including Madaidans Insecurities as the original basis for hardening, privsec's Desktop Linux Hardening, secureblue for the kernel module blacklist and kernel parameter inspiration, Kicksecure's security-misc for Bluetooth configuration, Tommy's Linux-Setup-Scripts for sysctl hardening, GrapheneOS infrastructure for optional chrony configuration, and Xe Iaso's blog for the idea of restricting nix to the wheel user. The project is not endorsed by any of them.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cynicsketch-nix-mineral)Was this useful?