secrets overhaul: use tpm for laptop (need to migrate desktop later)

This commit is contained in:
2026-04-23 14:05:43 -04:00
parent 22282691e7
commit e019f2d4fb
17 changed files with 218 additions and 25 deletions

View File

@@ -0,0 +1,70 @@
{
pkgs,
inputs,
...
}:
let
# rage cannot invoke age-plugin-tpm unless the plugin binary is on PATH at
# activation time. Wrap rage so the activation scripts (and anything else
# that picks up `age.ageBin`) get age-plugin-tpm for free.
rageWithTpm = pkgs.writeShellScriptBin "rage" ''
export PATH="${pkgs.age-plugin-tpm}/bin:$PATH"
exec ${pkgs.rage}/bin/rage "$@"
'';
in
{
imports = [
inputs.agenix.nixosModules.default
];
# Expose the plugin + agenix CLI for interactive edits (`agenix -e …`).
environment.systemPackages = [
inputs.agenix.packages.${pkgs.system}.default
pkgs.age-plugin-tpm
];
age.ageBin = "${rageWithTpm}/bin/rage";
# Primary identity: TPM-sealed key, generated by scripts/bootstrap-desktop-tpm.sh.
# Fallback identity: admin SSH key. age tries paths in order, so if the TPM
# is wiped or the board is replaced the SSH key keeps secrets accessible until
# the TPM is re-bootstrapped. Both are encrypted recipients on every .age file.
age.identityPaths = [
"/var/lib/agenix/tpm-identity"
"/home/primary/.ssh/id_ed25519"
];
# Ensure the identity directory exists before agenix activation so a fresh
# bootstrap doesn't race the directory creation.
systemd.tmpfiles.rules = [
"d /var/lib/agenix 0700 root root -"
];
age.secrets = {
# Secureboot PKI bundle (db/KEK/PK keys + certs) consumed by lanzaboote
# via desktop-lanzaboote-agenix.nix at activation time.
secureboot-tar = {
file = ../secrets/desktop/secureboot.tar.age;
mode = "0400";
owner = "root";
group = "root";
};
# netrc for the private nix binary cache.
nix-cache-netrc = {
file = ../secrets/desktop/nix-cache-netrc.age;
mode = "0400";
owner = "root";
group = "root";
};
# yescrypt hash for the primary user.
password-hash = {
file = ../secrets/desktop/password-hash.age;
mode = "0400";
owner = "root";
group = "root";
};
};
}

View File

@@ -17,9 +17,10 @@
./desktop-vm.nix
./desktop-steam.nix
./desktop-networkmanager.nix
./desktop-age-secrets.nix
./desktop-lanzaboote-agenix.nix
inputs.disko.nixosModules.disko
inputs.lanzaboote.nixosModules.lanzaboote
inputs.nixos-hardware.nixosModules.common-cpu-amd-pstate
inputs.nixos-hardware.nixosModules.common-cpu-amd-zenpower
@@ -50,16 +51,6 @@
mkdir -p /nix/var/nix/profiles/per-user/root/channels
'';
# extract all my secureboot keys
# TODO! proper secrets management
"secureboot-keys".text = ''
#!/usr/bin/env sh
rm -fr ${config.boot.lanzaboote.pkiBundle} || true
mkdir -p ${config.boot.lanzaboote.pkiBundle}
${lib.getExe pkgs.gnutar} xf ${../secrets/desktop/secureboot.tar} -C ${config.boot.lanzaboote.pkiBundle}
chown -R root:wheel ${config.boot.lanzaboote.pkiBundle}
chmod -R 500 ${config.boot.lanzaboote.pkiBundle}
'';
};
swapDevices = [ ];
@@ -71,7 +62,7 @@
trusted-public-keys = [
site_config.binary_cache.public_key
];
netrc-file = "${../secrets/desktop/nix-cache-netrc}";
netrc-file = config.age.secrets.nix-cache-netrc.path;
};
# cachyos kernel overlay
@@ -896,8 +887,7 @@
"camera"
"adbusers"
];
# TODO! this is really bad :( I should really figure out how to do proper secrets management
hashedPasswordFile = "${../secrets/desktop/password-hash}";
hashedPasswordFile = config.age.secrets.password-hash.path;
};
services.gvfs.enable = true;

View File

@@ -0,0 +1,49 @@
{
config,
lib,
pkgs,
inputs,
...
}:
{
imports = [
inputs.lanzaboote.nixosModules.lanzaboote
];
boot = {
loader.systemd-boot.enable = lib.mkForce false;
lanzaboote = {
enable = true;
# sbctl expects the bundle at /var/lib/sbctl; muffin uses /etc/secureboot
# because it is wiped on every activation there (impermanence) — desktops
# extract to the historical sbctl path so existing tooling keeps working.
pkiBundle = "/var/lib/sbctl";
};
};
system.activationScripts = {
# Extract the secureboot PKI bundle from the agenix-decrypted tar. Mirrors
# modules/server-lanzaboote-agenix.nix; skip when keys are already present
# (e.g., disko-install staged them via --extra-files).
"secureboot-keys" = {
deps = [ "agenix" ];
text = ''
#!/bin/sh
(
umask 077
if [[ -d ${config.boot.lanzaboote.pkiBundle} && -f ${config.boot.lanzaboote.pkiBundle}/db.key ]]; then
echo "secureboot keys already present, skipping extraction"
else
echo "extracting secureboot keys from agenix"
rm -fr ${config.boot.lanzaboote.pkiBundle} || true
install -d -o root -g wheel -m 0500 ${config.boot.lanzaboote.pkiBundle}
${pkgs.gnutar}/bin/tar xf ${config.age.secrets.secureboot-tar.path} -C ${config.boot.lanzaboote.pkiBundle}
fi
chown -R root:wheel ${config.boot.lanzaboote.pkiBundle}
chmod -R 500 ${config.boot.lanzaboote.pkiBundle}
)
'';
};
};
}

View File

@@ -1,4 +1,4 @@
{ hostname, site_config, ... }:
{ hostname, ... }:
{
# speed up boot times (by about three seconds)
systemd.services.NetworkManager-wait-online.enable = false;
@@ -9,7 +9,10 @@
networkmanager = {
enable = true;
appendNameservers = site_config.dns_servers;
appendNameservers = [
"1.1.1.1"
"9.9.9.9"
];
wifi = {
scanRandMacAddress = true;