Secrets storage on NixOS with password store
Deprecated
Deprecation warning. See the section on nix-sops for better secrets handling. The reason for deprecation:
- nix-plugins uses C and not Nix, this
can cause
nixos-rebuild
to break from incompatibility between versions (see this issue). - This way of doing things is hard to bootstrap. You cannot launch a new system
with the following config from a blank slate, since
builtins.extraBuiltins
is not available untilnix-plugins
is installed, so you can only use after at least one rebuild. - The secrets handled this will still be available in the nix store as plaintext. This is not a fault of nix-plugins but is due to my implementation laziness.
In this section we will implement a simple function that would retrieve secrets
from password-store
. It might be useful to go over the section on web
services (especially the one on git) after this so that you can sync
your password-store
to your server.
This section is actually a copy of this blog post. I will cut out the explanations as usual and make it cookbook style. It is actually fairly easy to implement.
First you need to enable the
nix-plugins plugin. Note that you
should ensure everything here is absolutely correct before rebuilding. An error
in your nix.conf
can make rebuilds or rollbacks impossible and may require
rebooting into an older configuration if goes sideways. For example: do not
rebuild after this stage, because we have not defined extra-builtins.nix
yet.
/etc/nixos/configuration.nixnix.extraOptions = ''
plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
extra-builtins-file = ${toString ./misc/extra-builtins.nix}
'';
Now we define extra-builtins.nix
. It will contain all of our extra functions
that have exec
capability.
/etc/nixos/misc/extra-builtins.nix{ exec, ... }:
{
getSecret = name: exec [ ./nix-pass.sh name ];
}
Simple enough. So this gives us access to a function
builtins.extraBuiltins.getSecret
that will return whatever nix-pass.sh
evaluates to. Now we define that script.
/etc/nixos/misc/nix-pass.sh#! /bin/sh
f=$(mktemp)
trap "rm $f" EXIT
su -c "pass show $1" <USER> > $f
nix-instantiate --eval --expr "builtins.readFile $f"
This script will log in to <USER>
, which should be the user that has access to
the correct password-store
. Then it retrieves the password that was supplied
as argument and returns it. Obviously before all this works, you should have set
up password-store
and GPG.