secrets overhaul: use tpm for laptop (need to migrate desktop later)
This commit is contained in:
68
scripts/bootstrap-desktop-tpm.sh
Executable file
68
scripts/bootstrap-desktop-tpm.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
# Bootstrap the age-plugin-tpm identity for a desktop host (mreow / yarn).
|
||||
#
|
||||
# Produces a TPM-sealed age identity at /var/lib/agenix/tpm-identity and
|
||||
# prints the legacy `age1tpm1…` recipient. The identity file is a TPM
|
||||
# handle, not key material — the actual key never leaves the TPM.
|
||||
#
|
||||
# --tpm-recipient is required: nixpkgs only ships `age-plugin-tpm`, not the
|
||||
# `age-plugin-tag` binary that rage looks up when it sees the new p256tag
|
||||
# `age1tag1…` format. Until a packaged age-plugin-tag lands, every recipient
|
||||
# stays in the legacy form so encryption works with off-the-shelf nixpkgs.
|
||||
#
|
||||
# Usage:
|
||||
# doas scripts/bootstrap-desktop-tpm.sh
|
||||
#
|
||||
# After running:
|
||||
# 1. Append the printed recipient to `tpm` in secrets/secrets.nix:
|
||||
# "age1tpm1… <hostname>"
|
||||
# 2. `agenix -r` (from a shell with age-plugin-tpm on PATH) to re-encrypt
|
||||
# every desktop secret with the new recipient list.
|
||||
# 3. Commit + `./deploy.sh switch`.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "this script must run as root (access to /dev/tpmrm0 + /var/lib/agenix)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
host=$(hostname -s)
|
||||
id_file=/var/lib/agenix/tpm-identity
|
||||
|
||||
install -d -m 0700 -o root -g root /var/lib/agenix
|
||||
|
||||
if [[ -f "$id_file" ]]; then
|
||||
echo "existing identity found at $id_file — preserving"
|
||||
else
|
||||
echo "generating TPM-sealed age identity..."
|
||||
nix run nixpkgs#age-plugin-tpm -- --generate --tpm-recipient --output "$id_file"
|
||||
chmod 0400 "$id_file"
|
||||
chown root:root "$id_file"
|
||||
fi
|
||||
|
||||
# Always derive the legacy age1tpm1… recipient, even if the identity file
|
||||
# was generated with the newer p256tag comment (Recipient line starts with
|
||||
# age1tag1…). `--convert --tpm-recipient` uses the same TPM object and just
|
||||
# serializes the public key point in the old format.
|
||||
recipient=$(nix run nixpkgs#age-plugin-tpm -- --convert --tpm-recipient < "$id_file" 2>/dev/null | grep -o 'age1tpm1[0-9a-z]*' | head -n1)
|
||||
if [[ -z "$recipient" ]]; then
|
||||
# fallback to parsing the header comment (only works when the identity was
|
||||
# already generated with --tpm-recipient).
|
||||
recipient=$(grep '^# Recipient:' "$id_file" | awk '{print $3}')
|
||||
fi
|
||||
if [[ -z "$recipient" ]]; then
|
||||
echo "failed to derive recipient for $id_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
recipient for $host:
|
||||
"$recipient $host"
|
||||
|
||||
next steps (run on a workstation with git-crypt unlocked):
|
||||
1. edit secrets/secrets.nix and append the line above inside the \`tpm\` list.
|
||||
2. nix run nixpkgs#agenix -- -r # re-encrypts every .age file.
|
||||
3. git commit + ./deploy.sh switch
|
||||
EOF
|
||||
Reference in New Issue
Block a user