Complete SOPS secrets management setup (#5)
Completed Issue #5: SOPS Secrets Management All objectives met: - ✅ Age encryption key generated (keys/age-key.txt) - ✅ SOPS configured with Age backend (.sops.yaml) - ✅ Secrets directory structure created - ✅ Example encrypted secrets (shared + test client) - ✅ Comprehensive documentation for key backup - ✅ Ready for Ansible integration Security measures: - Age private key gitignored (keys/age-key.txt) - Only encrypted .sops.yaml files committed - Plaintext secrets explicitly excluded - Key backup procedures documented Files added: - .sops.yaml - SOPS configuration with Age public key - secrets/shared.sops.yaml - Shared secrets (encrypted) - secrets/clients/test.sops.yaml - Test client secrets (encrypted) - secrets/README.md - Complete SOPS usage guide - keys/README.md - Key backup procedures - keys/.gitignore - Protects private keys Updated: - .gitignore - Allow .sops.yaml, block plaintext Tested: - Encryption: ✅ Files encrypted successfully - Decryption: ✅ Secrets decrypt correctly - Git safety: ✅ Private key excluded from commits Next: Ready for Zitadel/Nextcloud deployment with secure credentials Closes #5 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
4e72ddf4ef
commit
6bc8e508c6
7 changed files with 358 additions and 1 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,6 +1,7 @@
|
|||
# Secrets - NEVER commit these
|
||||
# Secrets - NEVER commit plaintext, only encrypted .sops.yaml files
|
||||
secrets/**/*.yaml
|
||||
secrets/**/*.yml
|
||||
!secrets/**/*.sops.yaml
|
||||
!secrets/.sops.yaml
|
||||
keys/age-key.txt
|
||||
*.key
|
||||
|
|
|
|||
7
.sops.yaml
Normal file
7
.sops.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SOPS Configuration
|
||||
# Defines encryption keys and rules for secret files
|
||||
|
||||
creation_rules:
|
||||
# All files in secrets/ directory
|
||||
- path_regex: secrets/.*\.sops\.yaml$
|
||||
age: age170jqy5pg6z62kevadqyxxekw8ryf3e394zaquw0nhs9ae3v9wd6qq2hxnk
|
||||
6
keys/.gitignore
vendored
Normal file
6
keys/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# NEVER commit Age private keys
|
||||
*.txt
|
||||
*.key
|
||||
|
||||
# Only allow README
|
||||
!README.md
|
||||
52
keys/README.md
Normal file
52
keys/README.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Age Encryption Keys
|
||||
|
||||
⚠️ **CRITICAL**: This directory contains encryption keys that are **NOT committed to Git**.
|
||||
|
||||
## Key Files
|
||||
|
||||
- `age-key.txt` - Age private key for SOPS encryption (GITIGNORED)
|
||||
|
||||
## Backup Checklist
|
||||
|
||||
Before proceeding with any infrastructure work, ensure you have:
|
||||
|
||||
- [ ] Copied `age-key.txt` to password manager
|
||||
- [ ] Created offline backup (printed or encrypted USB)
|
||||
- [ ] Verified backup can decrypt secrets successfully
|
||||
|
||||
## Key Recovery
|
||||
|
||||
If you lose access to `age-key.txt`:
|
||||
|
||||
1. **Check password manager** for backup
|
||||
2. **Check offline backups** (printed copy, USB drive)
|
||||
3. **If no backup exists**: Secrets are PERMANENTLY LOST
|
||||
- You will need to regenerate all secrets
|
||||
- Re-encrypt all `.sops.yaml` files
|
||||
- Update all services with new credentials
|
||||
|
||||
## Generating a New Key
|
||||
|
||||
Only do this if you've lost the original key or need to rotate for security:
|
||||
|
||||
```bash
|
||||
# Generate new Age key
|
||||
age-keygen -o age-key.txt
|
||||
|
||||
# Extract public key
|
||||
grep "public key:" age-key.txt
|
||||
|
||||
# Update .sops.yaml in repository root with new public key
|
||||
|
||||
# Re-encrypt all secrets
|
||||
cd ..
|
||||
for file in secrets/**/*.sops.yaml; do
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops updatekeys -y "$file"
|
||||
done
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- This directory is in `.gitignore`
|
||||
- Keys should never be shared via email, Slack, or unencrypted channels
|
||||
- Always use secure methods for key distribution (password manager, encrypted channels)
|
||||
234
secrets/README.md
Normal file
234
secrets/README.md
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
# Secrets Management with SOPS + Age
|
||||
|
||||
This directory contains encrypted secrets for the infrastructure using [SOPS](https://github.com/getsops/sops) with [Age](https://github.com/FiloSottile/age) encryption.
|
||||
|
||||
## 🔐 Security Model
|
||||
|
||||
- **Encryption**: All secret files encrypted with Age before committing to Git
|
||||
- **Key Storage**: Age private key stored OUTSIDE this repository
|
||||
- **Git-Safe**: Only encrypted files (.sops.yaml) are committed
|
||||
- **Decryption**: Happens at runtime by Ansible or manually with `sops`
|
||||
|
||||
## 📁 Directory Structure
|
||||
|
||||
```
|
||||
secrets/
|
||||
├── README.md # This file
|
||||
├── shared.sops.yaml # Shared secrets (encrypted)
|
||||
└── clients/
|
||||
└── *.sops.yaml # Per-client secrets (encrypted)
|
||||
```
|
||||
|
||||
## 🔑 Age Key Location
|
||||
|
||||
**IMPORTANT**: The Age private key is stored at:
|
||||
```
|
||||
keys/age-key.txt
|
||||
```
|
||||
|
||||
This file is **gitignored** and must **NEVER** be committed.
|
||||
|
||||
### Key Backup Checklist
|
||||
|
||||
✅ **You MUST backup the Age key securely:**
|
||||
|
||||
1. **Password Manager**: Store in Bitwarden/1Password/etc
|
||||
```bash
|
||||
# Copy key content
|
||||
cat keys/age-key.txt
|
||||
# Store as secure note in password manager
|
||||
```
|
||||
|
||||
2. **Print Backup** (optional but recommended):
|
||||
```bash
|
||||
# Print and store in secure physical location
|
||||
cat keys/age-key.txt | lpr
|
||||
```
|
||||
|
||||
3. **Encrypted USB Drive** (optional):
|
||||
```bash
|
||||
# Copy to encrypted USB for offline backup
|
||||
cp keys/age-key.txt /Volumes/SecureUSB/infrastructure-age-key.txt
|
||||
```
|
||||
|
||||
⚠️ **WARNING**: If you lose this key, encrypted secrets are PERMANENTLY UNRECOVERABLE!
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
```bash
|
||||
# Install SOPS and Age
|
||||
brew install sops age
|
||||
|
||||
# Ensure you have the Age key
|
||||
ls -la keys/age-key.txt
|
||||
```
|
||||
|
||||
### View Encrypted Secrets
|
||||
|
||||
```bash
|
||||
# View shared secrets
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops secrets/shared.sops.yaml
|
||||
|
||||
# View client secrets
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops secrets/clients/test.sops.yaml
|
||||
```
|
||||
|
||||
### Edit Encrypted Secrets
|
||||
|
||||
```bash
|
||||
# Edit shared secrets (decrypts, opens $EDITOR, re-encrypts on save)
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops secrets/shared.sops.yaml
|
||||
|
||||
# Edit client secrets
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops secrets/clients/test.sops.yaml
|
||||
```
|
||||
|
||||
### Create New Client Secrets
|
||||
|
||||
```bash
|
||||
# Copy template
|
||||
cp secrets/clients/test.sops.yaml secrets/clients/newclient.sops.yaml
|
||||
|
||||
# Edit with generated passwords
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops secrets/clients/newclient.sops.yaml
|
||||
```
|
||||
|
||||
### Generate Secure Passwords
|
||||
|
||||
```bash
|
||||
# Random 32-character password
|
||||
openssl rand -base64 32
|
||||
|
||||
# Random 24-character password
|
||||
openssl rand -base64 24
|
||||
|
||||
# Zitadel masterkey (32-byte hex)
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
## 🔧 Usage with Ansible
|
||||
|
||||
Ansible automatically decrypts SOPS files using the `community.sops` collection.
|
||||
|
||||
**In playbooks:**
|
||||
```yaml
|
||||
- name: Load client secrets
|
||||
community.sops.load_vars:
|
||||
file: "{{ playbook_dir }}/../secrets/clients/{{ client_name }}.sops.yaml"
|
||||
name: client_secrets
|
||||
|
||||
- name: Use decrypted secret
|
||||
debug:
|
||||
msg: "DB Password: {{ client_secrets.zitadel_db_password }}"
|
||||
```
|
||||
|
||||
**Environment variable required:**
|
||||
```bash
|
||||
export SOPS_AGE_KEY_FILE=/path/to/infrastructure/keys/age-key.txt
|
||||
```
|
||||
|
||||
## 📝 Secret File Structure
|
||||
|
||||
### shared.sops.yaml
|
||||
|
||||
Contains secrets shared across all infrastructure:
|
||||
- Hetzner Cloud API token
|
||||
- Hetzner Storage Box credentials
|
||||
- ACME email for SSL certificates
|
||||
|
||||
### clients/*.sops.yaml
|
||||
|
||||
Per-client secrets:
|
||||
- Database passwords (Zitadel, Nextcloud)
|
||||
- Admin passwords
|
||||
- Zitadel masterkey
|
||||
- Restic repository password
|
||||
- OIDC credentials (after generation)
|
||||
|
||||
## 🛠️ Common Tasks
|
||||
|
||||
### Decrypt to Temporary File
|
||||
|
||||
```bash
|
||||
# Decrypt for one-time use
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops --decrypt secrets/shared.sops.yaml > /tmp/secrets.yaml
|
||||
|
||||
# Use the file
|
||||
cat /tmp/secrets.yaml
|
||||
|
||||
# IMPORTANT: Delete when done
|
||||
rm /tmp/secrets.yaml
|
||||
```
|
||||
|
||||
### Encrypt New File
|
||||
|
||||
```bash
|
||||
# Create plaintext file
|
||||
cat > secrets/newfile.sops.yaml <<EOF
|
||||
my_secret: "super-secret-value"
|
||||
EOF
|
||||
|
||||
# Encrypt in place
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops --encrypt --in-place secrets/newfile.sops.yaml
|
||||
```
|
||||
|
||||
### Re-encrypt with New Key
|
||||
|
||||
If you need to rotate the Age key:
|
||||
|
||||
```bash
|
||||
# Generate new key
|
||||
age-keygen -o keys/age-key-new.txt
|
||||
|
||||
# Get public key
|
||||
grep "public key:" keys/age-key-new.txt
|
||||
|
||||
# Update .sops.yaml with new public key
|
||||
|
||||
# Re-encrypt all files
|
||||
for file in secrets/**/*.sops.yaml; do
|
||||
SOPS_AGE_KEY_FILE=keys/age-key.txt sops updatekeys -y "$file"
|
||||
done
|
||||
|
||||
# Replace old key
|
||||
mv keys/age-key.txt keys/age-key-old.txt
|
||||
mv keys/age-key-new.txt keys/age-key.txt
|
||||
```
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### "Failed to get the data key required to decrypt the SOPS file"
|
||||
|
||||
- **Cause**: Age private key not found or incorrect
|
||||
- **Fix**: Ensure `SOPS_AGE_KEY_FILE` points to correct key
|
||||
```bash
|
||||
export SOPS_AGE_KEY_FILE=/full/path/to/keys/age-key.txt
|
||||
```
|
||||
|
||||
### "no matching creation rules found"
|
||||
|
||||
- **Cause**: File path doesn't match `.sops.yaml` regex
|
||||
- **Fix**: Ensure filename ends with `.sops.yaml`
|
||||
|
||||
### "config file not found"
|
||||
|
||||
- **Cause**: `.sops.yaml` not in repository root
|
||||
- **Fix**: Check `.sops.yaml` exists at repo root
|
||||
|
||||
## 🔒 Security Best Practices
|
||||
|
||||
1. ✅ **Never commit** `keys/age-key.txt`
|
||||
2. ✅ **Always encrypt** before committing secrets
|
||||
3. ✅ **Backup the key** in multiple secure locations
|
||||
4. ✅ **Use strong passwords**: minimum 24 characters
|
||||
5. ✅ **Rotate secrets** periodically
|
||||
6. ✅ **Limit key access** to essential personnel only
|
||||
7. ✅ **Delete temp files** after decryption
|
||||
|
||||
## 📚 References
|
||||
|
||||
- [SOPS Documentation](https://github.com/getsops/sops)
|
||||
- [Age Documentation](https://github.com/FiloSottile/age)
|
||||
- [Ansible SOPS Collection](https://docs.ansible.com/ansible/latest/collections/community/sops/)
|
||||
32
secrets/clients/test.sops.yaml
Normal file
32
secrets/clients/test.sops.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ENC[AES256_GCM,data:nK9yR3JOQB56nTI8H8g2Mp7vnb8wArivoQ==,iv:Ke/n7VHkQs1X5b8/kj7Put6BNuZvK5A1WDLdVNJvPAg=,tag:kLvhJ3KCBnO6qd9KSD0OLw==,type:comment]
|
||||
#ENC[AES256_GCM,data:L8VurAyFOT0RdJXab18xpAgW0ZULY9nxw/DdJ9kisEBfT+m0FZU=,iv:xv1i5wLoOR7x2N2ukuasGCrK2N5xHlfDdnwhaL+XBm8=,tag:LIzSGObX5NMloLU01T0iwg==,type:comment]
|
||||
#ENC[AES256_GCM,data:vMG1ExYmlXI1RWbQWyUdmKNCqg==,iv:l9TGHsz2KOqF1i6j39ftXxUYvlfAzXY5Bi5nAJMWSQA=,tag:cJ3lrld4vL7uJOnqQRmJjQ==,type:comment]
|
||||
client_name: ENC[AES256_GCM,data:MZWftQ==,iv:f5MS6vLBC+tHJlB+VWTpOWTej7+sJZKbioMfA37ZjiA=,tag:/h+aYKOh4BPh96CJlNzpJw==,type:str]
|
||||
client_domain: ENC[AES256_GCM,data:CtSIb4/bQU8etWJpTqudxZwhuUk+hqU=,iv:FZhFwV88FglVQzjgPNJW5ZizJtHQbfdFaUbeLWaU1io=,tag:3VNoF543JENvPbiLU/todg==,type:str]
|
||||
#ENC[AES256_GCM,data:BdAVkrQXKwMUuNr+P8iqGA==,iv:8Acn7K+tR2b8mkPe5EugAKpV9A540FVJC0kIuDQIPD4=,tag:jdfmiZ5o4dy8Q/YbZqq/ng==,type:comment]
|
||||
zitadel_db_password: ENC[AES256_GCM,data:Jt6C7U88Ale90QxSm7E4ZwluIbuLq3tWl0+tOFDpzP2og7eDyQ==,iv:fqvUJcK8h0xRSAzxsVOwSUyyL2CKlyvszCihL4syot8=,tag:rDXQIQ/0MDRftkDuz50Tkw==,type:str]
|
||||
zitadel_admin_password: ENC[AES256_GCM,data:apcy1CuWpICWULo8VULqH47loeFB3eUKLvUBIuVXIuu7BPwtbw==,iv:U7JB0wDhGKPwpRs1RE0X8dfcuE7sa5b9ikc+0XDWKos=,tag:YcT3y+1wRLfHsYoM4c/2yg==,type:str]
|
||||
zitadel_masterkey: ENC[AES256_GCM,data:PZHiQK3Z2IGE0DUp/DRsQ7omfNM0xKmiaPAQHn1D4vU1XuJ2t54=,iv:K11E24TK6886crExpEWF/eDF53w5lQzIt5BG5jS557Q=,tag:NFNY7rTdxKLUOxglCfdYRw==,type:str]
|
||||
#ENC[AES256_GCM,data:UCxVKl+EGvZvHFHZa91rjlYI,iv:RmN4jI05bkM1uEE1TglzE5a54RYFYMzCMQvlpq2ydbg=,tag:POsM86j4Jj+8wjwF7ffWgA==,type:comment]
|
||||
nextcloud_db_password: ENC[AES256_GCM,data:oN+PC7pD07VyV9bKqZOGWLkdH6VhKOz+BBRmPYmm/8q4OQ47iQ==,iv:8ZAipySlXTgZm50R+AOKWQGszc+fcgKPMoa+TOFq+ig=,tag:6pEqOidt8Dz4P0QQ+7u+BQ==,type:str]
|
||||
nextcloud_admin_password: ENC[AES256_GCM,data:ZMoK4M6xAFK3DQIBMn0a1mtkKCjhW6P/dLfUUILccnjmqO8a3A==,iv:ctXQhhO5NK5/i2Hg73lnCy1bHlgXsgBjMxQPhJy2yrw=,tag:LzbWUwZ2AEQyx2lbshu73Q==,type:str]
|
||||
#ENC[AES256_GCM,data:J9fmtOMRn7VCA4qn3KN5L4QXuaNLBmk35q8NlqxMYg5TJg==,iv:f7DM3G1VN3rvIkFzAJrouG4d1A2jRtNWuJu5/+YezMQ=,tag:WA4qDSQH5+NSs/8tiHNM6Q==,type:comment]
|
||||
restic_repo_password: ENC[AES256_GCM,data:V3Pw2hZIFWD/uK+pXPETHNAula4SfmPQGEOEqw/v7KdcwMlhgQ==,iv:DukqTm/LtliLioALDwZI0BDW3sJwNfq/6vcHVIit0Gc=,tag:mNIHwcBtranAmJNBTl4thw==,type:str]
|
||||
#ENC[AES256_GCM,data:Jnxs5WoVDE31NgQmocYH80W569qK8yHDwY8ZDYeDyOY+Fn1mbK7xdilCB4aOn4vP5qtMzqCKa7paXm78BzZ9FpRgAkY=,iv:kgLwRvT5XhgDN7O4yEYkxMVFCuNtAdB+mmhYjar1pqY=,tag:fplXZLOILDOzh7n8WIWm/A==,type:comment]
|
||||
#ENC[AES256_GCM,data:xpilPXQdvCRTIBjWEfRZMfILlWi/gDGL7onkT9o=,iv:1XsMusNaqv80/TLLfdrBk56RqNCDTB0EavhQXBJVS3I=,tag:OXlrYZuldsJeyaJQBWeDPQ==,type:comment]
|
||||
#ENC[AES256_GCM,data:hwTLhDd5S4EWFFBcrkxGRazBVU50txHIKjKyOb3VJOqF,iv:7DGf0PvBKYN9NxhAiAi2bGThWf7jHmAhJDuqgGb+7+4=,tag:SO35c4iT8hBDlorx/6I8ww==,type:comment]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age170jqy5pg6z62kevadqyxxekw8ryf3e394zaquw0nhs9ae3v9wd6qq2hxnk
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWZko3UVJkSzRjK3J0bXBm
|
||||
Yk0rUTRRbmxYL001QXNEMHpIaGsvMUc2ZjFnCnZnTU8ySHc0QVB6amgrTjBPdG5w
|
||||
TFhucW9VZHNDWmdaVDdZWDRQbjhOQzAKLS0tIHJWWm00VWVIZlNXd04veGRoTkIw
|
||||
R0kyRC9VcTFoWkFCUnl6ZmlyRjh3bXcKCkAed8Gx9jxFmoFg7vyM4a3xO9N+FxtI
|
||||
CdpnZ9Wk1O498wPIV2meM3RFBclkWFgqGvAqzUNbzGuMnoSlRfJq+w==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-12-27T13:19:53Z"
|
||||
mac: ENC[AES256_GCM,data:XkD2lptFXJrRmKg/Rxd25D1Y2bGxKM+GqBcgXQTDXvr+BIrE5jC9AWzycmkB+GX0Ta5LYlcLk1mrXGp/SbNxE8rubCvqS7qZbpxEBQi8fsy+LX0kiCOgM5SSxMM6ON/gSJ2eivLzpEbeBGwXau77fNm/2MAAWZIdlfzeIN/9o4I=,iv:MU1pp6+rr7Gvs6mCPMUqz6VnPGLttUB0dgZsb43WyH4=,tag:ts54uUviBdmHif9KiQfrKQ==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.11.0
|
||||
25
secrets/shared.sops.yaml
Normal file
25
secrets/shared.sops.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ENC[AES256_GCM,data:MNLUiYAc9T7qkQQJbVRdw/bMIjRLGAFZySZUGF0T8k1xBtP3hRhp5cI=,iv:IDaJgax/Slpn+AeTCfl3wX5i1oRjCLfzVAfO7FTvOiw=,tag:OjKdnUsBo1ZXJWvM191pog==,type:comment]
|
||||
#ENC[AES256_GCM,data:I0PUaOrJWwHUpAXWVVdpzgubLhQqtvbXaxpnuFWwdDI5fdO98rg=,iv:Ow8NPenrdXDB4qC+IO+2wX5hylCaaTDkac7E6DDHffE=,tag:WpGJGI+OzgCInOc2eKN9UQ==,type:comment]
|
||||
#ENC[AES256_GCM,data:wMIcXre4zoR4MPGMGlNM6wZZ81sL7QSjk++ZyUmCxJDF0F3BtlCT2XCwKZBX6/ULEvJGm4H2aVc=,iv:1RnvNQAB72SPRNsaLbLWCKloWNrdiL75vTcJ6E0EjLY=,tag:H86RhqoruUnvjBmuvzYPKg==,type:comment]
|
||||
hcloud_token: ENC[AES256_GCM,data:4rJp1/Z/4PrHRUNq5oD4EhmyZrWnzKcQJfJeg0dif59nL6kw4Q==,iv:KTbPG5ngZAneKUShbUTQ6NwHjLQO7CunkSiIZDgF79Q=,tag:rUBqJYcOvR/F3SVnPjmp2A==,type:str]
|
||||
#ENC[AES256_GCM,data:yksU9TbbH85os7wjqUspVaDLCIbAj4vFhGlTzlt7niRFCRZmHfTsdQobC6o0Xw==,iv:XOrfoiBmQ1elOqTlvLh3u2FHrMq1cp5Zf67emKDQpGo=,tag:S59pVXvJW6KSJ2EqLu4IHg==,type:comment]
|
||||
storage_box_host: ENC[AES256_GCM,data:D5Hzi16Z46GFNE8VHbKV8i8iEH7hIdlDQS0=,iv:jhCitS25tZMsE6UZ+tJkanXJNX6DQfOn30+7cQDNs60=,tag:EpzUyXhZCL6EEbnicY1BPg==,type:str]
|
||||
storage_box_user: ENC[AES256_GCM,data:P+rWUs+QwA==,iv:aVdWOfVkf7P5y8WlUP5ga8H7woEdGaFSUUbycDOPGYI=,tag:+lvTwQN4vOKRj5lNGZTiXw==,type:str]
|
||||
storage_box_password: ENC[AES256_GCM,data:corwnHJVanBt1/ELlVJwf1klVnR3WB6oUFtxoCQz+XYE,iv:egM5VqRx4N3zSrR37cCfBfml00AFRk1/UecWhaVrgS0=,tag:9Z1vXlPgyM57X9CAuRYV8w==,type:str]
|
||||
#ENC[AES256_GCM,data:WQ4w3gItBICoC9tgNoecH+2nppf0aqX+6h5a,iv:pIfewJ7Ee6P6FLClOSJUFs7Jl/nXyIkHN8rGsM6InHE=,tag:zWb46M0jzB7N4Z1Of7cT3w==,type:comment]
|
||||
acme_email: ENC[AES256_GCM,data:UbNndaUjrUj7+S6z3o7JlelE0EUZsP6T,iv:cMYKvkxHEIgW0G2vSmARry01K22WALRi8QVs/8BkdCA=,tag:nYgZiDfvLazBzo+2HU8XUA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age170jqy5pg6z62kevadqyxxekw8ryf3e394zaquw0nhs9ae3v9wd6qq2hxnk
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHQnBBTGZSVHg1YVNGb0Qw
|
||||
UllrYVlON0l5U2Qvek5zTXlBekNTNnd3ZkZ3Ck1xcVF1UGhLMGVrREw0cEkwbWpB
|
||||
Vjl3cW1Kby9GTWZpWUZqM3g2YjllcG8KLS0tIDY0eEpOMmtJTmxua28wQytmMkJy
|
||||
c0NBVERZZmV6L2lYaHVlb3lEK3Q4ejQKz/oho9gId2Fm9eM2Vl/JRKC5VL2Wj9as
|
||||
bz4wd7rRjvt1nwJsH10EqB7hf7lq9ukxdkzDySH+0haaZT64G8TcNw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-12-27T13:19:44Z"
|
||||
mac: ENC[AES256_GCM,data:tWwoGOH2s2LJYCYZII7urlWCs2CZ9M0PyhONlCwcApc3ykMvD8OVQsWiGqJpDfbZHaz5Vy7XWnINuFF99u4cOJpqQPFe8q8cRluURDUJ8aMOI05/jbzFqhPyzgtJ4OvZVyrm2LxlrYMtuBfo1NSVmGeHLhus0jD3P6cCY09Yew4=,iv:7s/lzOtNTa3wj5JwIBuMkGzCFRbtzd9+y3sG0Hbd458=,tag:c7G+S/usZvu9/QOA2lOsKA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.11.0
|
||||
Loading…
Add table
Reference in a new issue