#!/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… " # 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 <