BIOS 2423→4101 update on yarn required an fTPM reset, which broke the sealed age identity at /var/lib/agenix/tpm-identity. Bootstrapped a new identity against the new SRK and rotated yarn's recipient. age-plugin-tpm 1.0+ emits age1tag1… (p256tag) recipients by default and refuses to encrypt to legacy age1tpm1… ones, so rotated mreow's recipient to the same encoding (same key, new bech32 HRP) and added an age-plugin-tag→age-plugin-tpm symlink in the rage wrapper so rage's plugin dispatch finds the binary under the new prefix. Stripped the trailing host labels from the tpm recipient strings — rage's stricter bech32 parser now rejects the trailing whitespace; labels live in adjacent Nix comments instead.
92 lines
2.8 KiB
Nix
92 lines
2.8 KiB
Nix
{
|
|
pkgs,
|
|
inputs,
|
|
...
|
|
}:
|
|
let
|
|
# age-plugin-tpm 1.0+ defaults to the new age1tag1… (p256tag) recipient
|
|
# encoding and refuses to encrypt to legacy age1tpm1… recipients. rage's
|
|
# plugin dispatch maps recipient prefixes to binaries (`age1tag1…` →
|
|
# `age-plugin-tag`), but nixpkgs only ships `age-plugin-tpm`. Provide a
|
|
# symlink so both prefixes resolve to the same binary.
|
|
age-plugin-tpm-with-tag = pkgs.symlinkJoin {
|
|
name = "age-plugin-tpm-with-tag";
|
|
paths = [ pkgs.age-plugin-tpm ];
|
|
postBuild = ''
|
|
ln -s age-plugin-tpm $out/bin/age-plugin-tag
|
|
'';
|
|
};
|
|
|
|
# Wrap rage so the plugin (under both names) is on PATH at activation time.
|
|
rageWithTpm = pkgs.writeShellScriptBin "rage" ''
|
|
export PATH="${age-plugin-tpm-with-tag}/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";
|
|
};
|
|
|
|
# Master password for oo7-daemon's 'Login' keyring; the unit consumes it
|
|
# via systemd's ImportCredential machinery (see desktop-oo7-daemon.nix).
|
|
# Owner is `primary` so the user-scope systemd unit can LoadCredential it.
|
|
oo7-keyring-password = {
|
|
file = ../secrets/desktop/oo7-keyring-password.age;
|
|
mode = "0400";
|
|
owner = "primary";
|
|
group = "users";
|
|
};
|
|
|
|
};
|
|
}
|