I treat secrets like dependency injection: You don't make a thing that knows how to connect to the database / knows a secret / knows how to get a secret. Instead, you make a thing that takes an argument that is a database connection / secret. You bind late — at execution time. This keeps things very simple and needs no special frameworks / libraries / secrets-tools.
Concrete example:
- Passing a secret to a VM
- by wrapping it in a script
- that copies the secret into an ephemeral filesystem image
- that the VM mounts
In demo.nix:
{ pkgs ? import { }, }:
let
vmConfiguration = { lib, modulesPath, ... }: {
imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ];
config = {
networking.hostName = "demo";
system.stateVersion = lib.versions.majorMinor lib.version; # Ephemeral
boot.initrd.availableKernelModules = [ "iso9660" ];
fileSystems = lib.mkVMOverride {
"/suitcase" = {
device = "/dev/disk/by-label/suitcase";
fsType = "iso9660";
options = [ "ro" ];
};
};
systemd.services.demo-secret-access = {
description = "Demonstrate access to secret";
wants = [ "suitcase.mount" ];
after = [ "suitcase.mount" ];
wantedBy = [ "multi-user.target" ];
script = ''
echo "Demo: The secret is: $(cat /suitcase/secret)" >&2
'';
};
};
};
vmWrapper = { nixos, cdrtools, writeShellApplication, }:
writeShellApplication {
name = "demo";
runtimeInputs = [ cdrtools ];
text = ''
if (( $# < 1 ));then
echo usage: demo suitcase_path ... >&2
exit 1
fi
if [[ ! -d "$1" ]];then
echo Expected first argument to be a directory >&2
exit 1
fi
suitcase_contents=$(realpath "$1")
shift
d=
trap '[[ "$d" && -e "$d" ]] && rm -r "$d"' EXIT
d=$(mktemp -d)
cd "$d"
(umask 077; mkisofs -R -uid 0 -gid 0 -V suitcase -o suitcase.iso "$suitcase_contents")
${(nixos vmConfiguration).config.system.build.vm}/bin/run-demo-vm \
-drive file="$d/suitcase.iso",format=raw,id=suitcase,if=none,read-only=on,werror=report \
-device virtio-blk-pci,drive=suitcase \
"$@"
'';
};
in pkgs.callPackage vmWrapper { }
Use:
$ mkdir foo
$ (umask 077; echo hello > foo/secret)
$ $(nix-build demo.nix)/bin/demo foo
and the VM logs:
Nov 15 01:31:27 demo demo-secret-access-start[639]: Demo: The secret is: hello
No?