This document describes the planned approach for managing encrypted secrets in this repository.
Secrets will be encrypted using age with multiple recipients, allowing any authorized device to decrypt. On macOS, keys will be backed by the Secure Enclave and protected with Touch ID. On Linux, standard age keys will be stored on disk.
Each Mac will have a hardware-backed key that never leaves the Secure Enclave. This requires macOS Sequoia or later.
Create the key:
sc_auth create-ctk-identity -l ssh -k p-256-ne -t bioExport the public key:
ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N ""
# Creates id_ecdsa_sk_rk.pubAdd to shell profile for seamless SSH/age integration:
export SSH_SK_PROVIDER=/usr/lib/ssh-keychain.dylibTODO: Document Linux key setup when we get there.
All public keys are collected in a recipients file. A secret encrypted to these keys can be decrypted by any single one of them.
# recipients.txt
# Mac 1 - Secure Enclave (Touch ID required)
ecdsa-sha2-nistp256 AAAA... mac1
# Mac 2 - Secure Enclave (Touch ID required)
ecdsa-sha2-nistp256 AAAA... mac2
age -R recipients.txt -o secret.age secret.txtFor YAML/JSON configuration files, sops encrypts individual values while keeping keys visible:
sops --encrypt --age "age1...,age1..." secrets.yaml > secrets.enc.yamlOr configure .sops.yaml for automatic key selection:
creation_rules:
- path_regex: secrets/.*\.yaml$
age: >-
age1abc...,
age1def...Then simply:
sops secrets/api-keys.yamlage -d -i ~/.ssh/id_ecdsa_sk_rk secret.agesops automatically finds keys in standard locations:
sops secrets/api-keys.yaml # Opens decrypted in $EDITOR
sops -d secrets/api-keys.yaml # Prints decrypted to stdout- Generate a key on the new device
- Add the public key to
recipients.txt - Re-encrypt all secrets to include the new recipient:
sops updatekeys secrets/file.yaml
- Remove the public key from
recipients.txt - Re-encrypt all secrets:
sops updatekeys secrets/file.yaml
- Rotate any secrets the device had access to (it may have decrypted them previously)
There is no practical way to run age or sops on iOS. Secrets that need to be accessible on iPhone should be stored separately in iCloud Keychain or a password manager.
Secure Enclave keys are non-exportable by design. If a Mac is lost or wiped, that key is gone. This is acceptable because secrets are encrypted to multiple recipients—other devices can still decrypt. Just remove the lost device's public key and re-encrypt.
The plan is to use sops-nix for integration with NixOS. This will:
- Store encrypted secrets in this repository
- Decrypt them at activation time to
/run/secrets/ - Reference the decrypted paths in Nix configurations
This keeps secrets encrypted at rest in git while making them available to services and configurations at runtime.