Add offline sops recovery key

Secrets now encrypted to three recipients:
- vultr_vps: server SSH host key (primary)
- admin: workstation key (local editing)
- recovery: offline key at ~/.config/sops/age/recovery.key

If server dies and admin key unavailable, recovery key can
still decrypt secrets to bootstrap restore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Dan 2026-01-10 15:40:31 -08:00
parent 5db6c0dc7e
commit 85989ccc2a
2 changed files with 37 additions and 10 deletions

18
.sops.yaml Normal file
View file

@ -0,0 +1,18 @@
keys:
# Vultr VPS jrz1 (45.77.205.49) - SSH host key converted to age
- &vultr_vps age1vuxcwvdvzl2u7w6kudqvnnf45czrnhwv9aevjq9hyjjpa409jvkqhkz32q
# Admin workstation - for local editing
- &admin age18ue40q4fw8uggdlfag7jf5nrawvfvsnv93nurschhuynus200yjsd775v3
# Offline recovery key - stored at ~/.config/sops/age/recovery.key
# Use this to decrypt secrets if server is dead and admin key unavailable
- &recovery age1kyhk90n8yvsqekr3f0094vy30uj2v40fq3dxe50pvf9rtfm9qa9stl6t3k
creation_rules:
- path_regex: secrets/secrets\.yaml$
key_groups:
- age:
- *vultr_vps
- *admin
- *recovery

View file

@ -16,20 +16,29 @@ sops:
- recipient: age1vuxcwvdvzl2u7w6kudqvnnf45czrnhwv9aevjq9hyjjpa409jvkqhkz32q
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuTm1DNzZjM1VmSVU2NlA0
RUFpZ2h0Snc0ZlVsc04zanBQZmcyaFh0aUc4CnNOQ0ZUS25xeTUwV1A0MzZFQzBT
NmhjVzVZR2gzb21iTFM2cDJRV0NDa3cKLS0tIG85RnRzYWQvNjNUMnN2bUJ6UUNn
Smp1ZkMwZ1RBb1NmWExYc280c20zYjAKwyChuUih0BTk7nYsit6aBkGDAzJV0xBa
gi2/bk5uLk7cW+JU46IrK9VPN6VhexDqN0k9ub3YMXNxfurn3wMNIg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5WmdhajB2eUZCMlNsTG9U
WFBkMVgwUFpMRHdSeXE1bU9QdUd1dThHaWxVCmVjL09GKzUwbnVzZUdEMCtNWnR6
L0R0U1ZXOUU5RnB4NlpDRWo4cjh4bEEKLS0tIFZBZGR2MjFnN1VEUmpsNFNmR1pN
NFI1V3JSN3RpeDZlMWVVbUQ5ZzV2ZWsKz84ccpTjhfmbWsNyptFSotjNAbrwURX4
RLJSjmov6eOMrwu3eJJF/WAhGonz++46WyD7ygSw4gtc88wzBjlCdw==
-----END AGE ENCRYPTED FILE-----
- recipient: age18ue40q4fw8uggdlfag7jf5nrawvfvsnv93nurschhuynus200yjsd775v3
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkWlVpbGFPY04wbjVhQndX
cEpuVzliTkFocUhDMGhnNmNxek9pcXNLeEFRCmNWc1dHMFBpMWcxYkg2MEdYTjRs
YjVreWpHbng0dTBIQkM2QzBHM0EwMmMKLS0tIGFkYVprTytHSEc4TXR1NGc0V2VC
TFF5cmRNSFE2ODBjOVBTemFNUzQrREEKyzPRDrmR68VKmjDLoJ89Yz+9A0tQPMB9
1+0/F+3OAbk66FTycap4E2mIqxLFWifW2h7tOfP2exxXFktCQcgmyA==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSUk1qNHFvMVRWVXFrZVNU
aVJlTmdmM3pzL1BDcEdPVVpqNjFqYUFsWFZrCmpGWTJBd2wrVUFjRVo0bGYvZ21h
Zk5JWnUzK1FHUXF5TkFSdVZOeER0dVUKLS0tIHBLak5xZkcvNUh2L2c5K2VNdnB0
VGxSVGNTNmFVRlJZTVBvYVRmUFMraVUKRVGiIq4+GESXHcHzl+pggn3KOF7LrcAb
4UjGwZmAZ3rDuSn/RQf17A0xABwkIuRotNTjQ/XPcIUhlVsWhVm1bg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1kyhk90n8yvsqekr3f0094vy30uj2v40fq3dxe50pvf9rtfm9qa9stl6t3k
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmSklEZm5ncDJlWXAvRFJV
ck9STVJjT3YvbzlKTTVUalFldkpETGlteW13CnRGNlRQM0J5ZGR3aFVOcFJwKzJZ
MitydW8raFBtTHhRYWt5NHIwRlNDU2MKLS0tIEtmVnI5d1R6cWJGMk5ORXJmQzZX
Y01xOHdGZ2tmL2NyZkJwRU82dGF5SUEK4qfPmXNbIw/vZv1PzMDB7Ya4bB+kl0HJ
XBV4M9UWzJ1Zi0qJzsk/HTKAk1147NAKH+koYaK03TPqf3Wkk3AHoQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-01-10T21:48:44Z"
mac: ENC[AES256_GCM,data:HGGz77ONHpz/OjwJU1+F+D+MJyHJP/UrCytjrYKTRK1pirNsJWyCwWDSKkpXvLt3vgJBlnWLgzbCk9Bp7NpYOO+QooRETdIqaZHSpEGoQjcJjY1o/8j4/THxwTb0Yh5mVZKQg39tEGIFOIcYc8HLPBLGQEbh6JGN2F/4r5PseWI=,iv:70QniATCsMmRfpdPbDspUle35Okxj1y4AhEJvY1CpQI=,tag:HnsKH/qqC9bUsk2aHSkTZQ==,type:str]