2025-09-13 20:47:24 +02:00
|
|
|
|
# 🔑 Managing Age Keys for Secrets
|
|
|
|
|
|
|
|
|
|
|
|
This project uses [**age**](https://age-encryption.org) + [**SOPS**](https://github.com/getsops/sops) to manage secrets in Git.
|
|
|
|
|
|
You need to create your own **age keypair**, add the public key to the repo, and configure SOPS to use it.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-09-13 22:48:15 +02:00
|
|
|
|
## 0. Install Age & Sops
|
|
|
|
|
|
|
|
|
|
|
|
First, make sure **age** is installed on your workstation.
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sudo apt update
|
|
|
|
|
|
sudo apt install age
|
|
|
|
|
|
age --version
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
To install Sops grab the binary release and install it.
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
wget https://github.com/getsops/sops/releases/download/v3.10.2/sops_3.10.2_amd64.deb
|
|
|
|
|
|
sudo apt install ./sops_3.10.2_amd64.deb
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-13 20:47:24 +02:00
|
|
|
|
## 1. Generate an Age Keypair
|
|
|
|
|
|
|
|
|
|
|
|
On your workstation, run:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2025-09-13 22:48:15 +02:00
|
|
|
|
age-keygen -o ~/.config/sops/age/key.txt
|
2025-09-13 20:47:24 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-09-13 22:48:15 +02:00
|
|
|
|
- This creates a new keypair and stores it at `~/.config/sops/age/key.txt`.
|
2025-09-13 20:47:24 +02:00
|
|
|
|
- The private key must **never** be committed to Git. Keep it safe (e.g., in your password manager or vault).
|
|
|
|
|
|
- The public key looks like this:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
age1qlf....yourpublickey....
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Add Your Public Key to the Repo
|
|
|
|
|
|
|
|
|
|
|
|
Create (or overwrite) the file:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
keys/age.pub
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Put your **public key** inside, e.g.:
|
|
|
|
|
|
|
|
|
|
|
|
```txt
|
|
|
|
|
|
age1qlf....yourpublickey....
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Commit this file:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
git add keys/age.pub
|
|
|
|
|
|
git commit -m "Add my age public key"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Update `.sops.yaml`
|
|
|
|
|
|
|
|
|
|
|
|
Open `.sops.yaml` in the repo and add your age public key under `creation_rules`:
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
creation_rules:
|
|
|
|
|
|
- path_regex: secrets/.*$
|
|
|
|
|
|
key_groups:
|
|
|
|
|
|
- age:
|
|
|
|
|
|
- age1qlf....yourpublickey....
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
You can list multiple keys if several people need access.
|
|
|
|
|
|
|
|
|
|
|
|
Commit the update:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
git add .sops.yaml
|
|
|
|
|
|
git commit -m "Configure SOPS with my age key"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. Test Encryption/Decryption
|
|
|
|
|
|
|
|
|
|
|
|
Encrypt a file:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sops -e secrets/example.yaml > secrets/example.enc.yaml
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Decrypt it back:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sops -d secrets/example.enc.yaml
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
If everything works, you are ready to store secrets securely in Git.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-09-13 22:52:18 +02:00
|
|
|
|
## 🔑 Secrets Handling Digest
|
|
|
|
|
|
|
2026-07-25 15:13:41 +02:00
|
|
|
|
In `railiance-infra`, **age private keys never leave your workstation**.
|
|
|
|
|
|
Secrets in the repo are encrypted to one or more **public keys** listed in
|
|
|
|
|
|
`.sops.yaml`. To decrypt, you either load your private key into the environment
|
|
|
|
|
|
(`SOPS_AGE_KEY`) or keep it in your local `~/.config/sops/age/keys.txt` (never
|
|
|
|
|
|
in Git). Ansible and Terraform decrypt files only on the control machine, so
|
|
|
|
|
|
plaintext is injected at runtime but never stored on servers. For teams, simply
|
|
|
|
|
|
add multiple public keys as recipients; each operator decrypts with their own
|
|
|
|
|
|
private key. In CI/CD, the private key is injected securely as a secret
|
|
|
|
|
|
variable. This ensures encryption is repo-wide and portable, while private keys
|
|
|
|
|
|
remain personal, local, and outside version control.
|
2025-09-13 22:52:18 +02:00
|
|
|
|
|
2025-09-13 20:47:24 +02:00
|
|
|
|
✅ That’s it — your secrets are now protected with your own master key.
|