system-git-sync/docs/HSM-CUSTODY.md
George Lambert aa7c837493
Some checks are pending
review / inventory (push) Waiting to run
S25: HSM custody, sync.pfc, georgelambert.org/pfc deep links
UserReview leftovers implemented without rewriting 70 website repos
and without fail-closing pfc-py-admin.
2026-09-15 23:19:44 -04:00

1.7 KiB

HSM / key custody

This is not a HIPAA/SOC 2/ISO certificate.

What lives where

Key Lab (ns1) Production
Config Ed25519 /opt/pfc/etc/sm-keys/config.ed25519.pem mode 0600 root Customer HSM / PKCS#11; public half in signed wrapper sig.key_id
NPE HPKE /opt/pfc/etc/npe/lab.seed + lab.npeid (host only) npe keygen --rotate --id on HSM-backed seed; inbox id unchanged
System bounce crypto.system_key_id in signed payload Same id; private material in HSM
Session / Google /opt/pfc/etc/admin.env Secrets manager; never git

Private files are never committed. Public PEMs and .npeid may be copied.

Rotate config signing key (lab)

sudo python3 /opt/pfc/python/secure_messaging/../scripts/rotate_config_key.py
# or from the repo:
sudo python3 scripts/rotate_config_key.py \
  --pem /opt/pfc/etc/sm-keys/config.ed25519.pem \
  --signed /opt/pfc/etc/secure-messaging.signed.json \
  --history /opt/pfc/data/admin/admin-history \
  --actor rotate-lab

Writes a new PKCS8 PEM, re-signs the current payload, appends prev+new+diff to the admin-history cube. Old PEM is kept as config.ed25519.pem.prev.

Rotate NPE encryption key (lab)

sudo /opt/pfc/bin/npe keygen --rotate --id /opt/pfc/etc/npe/lab.seed

Inbox (npe.inbox.<fp>) stays stable. Previous enc keys are retained for --keep-old then npe keygen --wipe-old --id ....

Production HSM (not on ns1)

Guess until hardware is attached: PKCS#11 slot for Ed25519 config signatures; NPE seed never leaves the module. PFC_CONFIG_KEY_PEM is replaced by PFC_CONFIG_KEY_PKCS11=pkcs11:token=.... Unsigned wrappers still rejected.