ready for runners
This commit is contained in:
parent
fc9971ddc9
commit
7dd5043b5d
49 changed files with 2569 additions and 1085 deletions
59
nixos/secrets/HOWTO.md
Normal file
59
nixos/secrets/HOWTO.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
### 🔧 Using Secrets in NixOS Configurations
|
||||
|
||||
You can use decrypted SOPS secrets in your `configuration.nix`, service modules, and flake-based setups.
|
||||
|
||||
#### 🔑 1. Use as environment variable (e.g. password)
|
||||
|
||||
```nix
|
||||
systemd.services.my-service.serviceConfig.EnvironmentFile =
|
||||
config.sops.secrets."my-password".path;
|
||||
```
|
||||
|
||||
> Your `secrets.yaml` should contain:
|
||||
>
|
||||
> ```yaml
|
||||
> my-password: PASSWORD=supersecret
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
#### 🗂 2. Use as file source (e.g. private key or token)
|
||||
|
||||
```nix
|
||||
environment.etc."ssh/id_ed25519".source =
|
||||
config.sops.secrets."ssh-private-key".path;
|
||||
```
|
||||
|
||||
> This places the decrypted secret at `/etc/ssh/id_ed25519` with appropriate permissions.
|
||||
|
||||
---
|
||||
|
||||
#### 👤 3. Read a secret value directly (not recommended for sensitive data)
|
||||
|
||||
```nix
|
||||
# Use a secret as a string value in a setting
|
||||
services.myapp.settings.apiKey = builtins.readFile config.sops.secrets."api-key".path;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 🛠 4. Use in systemd preStart scripts
|
||||
|
||||
```nix
|
||||
systemd.services.my-service.preStart = ''
|
||||
export PASSWORD=$(<${config.sops.secrets."my-password".path})
|
||||
./myapp --auth $PASSWORD
|
||||
'';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 🧠 5. Use in Forgejo user creation
|
||||
|
||||
```nix
|
||||
systemd.services.forgejo.preStart = ''
|
||||
${lib.getExe cfg.package} admin user create \
|
||||
--username admin \
|
||||
--password "$(tr -d '\n' < ${config.sops.secrets."admin-password".path})"
|
||||
'';
|
||||
```
|
||||
|
|
@ -1,51 +1,104 @@
|
|||
# 🔐 Secrets Management (with SOPS + Nix)
|
||||
|
||||
🔑 2. Generate an age Keypair
|
||||
This directory contains encrypted secrets used across the infrastructure managed by NixOS and [sops-nix](https://github.com/Mic92/sops-nix). Secrets are stored using [SOPS](https://github.com/mozilla/sops) and encrypted with an `age` key located on each host at `/etc/sops/age.key`.
|
||||
|
||||
age-keygen -o secrets/age.key
|
||||
---
|
||||
|
||||
This will output something like:
|
||||
|
||||
# created: 2025-06-02T22:00:00Z
|
||||
# public key: age1abcdefghijk...
|
||||
|
||||
Copy that public key somewhere — you’ll need it for encrypting.
|
||||
|
||||
✅ You should now have:
|
||||
## 📁 Directory Structure
|
||||
|
||||
```
|
||||
secrets/
|
||||
├── age.key # keep this safe and private!
|
||||
├── forgejo/
|
||||
│ └── secrets.yaml # Forgejo-specific secrets (admin password, DB password, secret key)
|
||||
├── runner/
|
||||
│ └── secrets.yaml # Forgejo runner secrets (tokens, etc.)
|
||||
├── shared/
|
||||
│ └── secrets.yaml # Shared secrets used across multiple VMs (SSH keys, tokens)
|
||||
````
|
||||
|
||||
📝 3. Create Encrypted Secrets File
|
||||
---
|
||||
|
||||
sops --age age1abcdefghijk... secrets/secrets.yaml
|
||||
## 🛠 SOPS Basics
|
||||
|
||||
This opens a YAML file in your $EDITOR. Add secrets like:
|
||||
### ✅ Encrypt a **new secret file**
|
||||
|
||||
forgejo-admin-password: "my-super-secret-password"
|
||||
```bash
|
||||
sops --age <YOUR-AGE-PUBKEY> -e > secrets/myservice/secrets.yaml
|
||||
````
|
||||
Example:
|
||||
```bash
|
||||
sops --age $(cat ~/.config/sops/age/keys.txt | grep public) -e > secrets/forgejo/secrets.yaml
|
||||
```
|
||||
> Press `i` to enter edit mode if prompted, or fill it using YAML format:
|
||||
```yaml
|
||||
admin-password: hunter2
|
||||
db-password: supersecret
|
||||
```
|
||||
|
||||
Save and close the file — it’s now encrypted using the public key.
|
||||
---
|
||||
|
||||
✅ Now you should have:
|
||||
### ✏️ Edit secrets in an existing file
|
||||
|
||||
secrets/
|
||||
├── age.key
|
||||
├── secrets.yaml # encrypted file (safe to commit)
|
||||
```bash
|
||||
sops secrets/forgejo/secrets.yaml
|
||||
```
|
||||
|
||||
You can commit secrets.yaml, but do not commit age.key unless you're OK with putting it on a VM.
|
||||
---
|
||||
|
||||
## 🧬 Using Secrets in Nix
|
||||
|
||||
🧪 Test Decryption Locally
|
||||
### 🧩 Option 1: Reference shared secrets (via `defaultSopsFile`)
|
||||
|
||||
export SOPS_AGE_KEY_FILE=secrets/age.key
|
||||
```nix
|
||||
# shared-sops.nix
|
||||
{
|
||||
sops = {
|
||||
age.keyFile = "/etc/sops/age.key";
|
||||
defaultSopsFile = ../secrets/shared/secrets.yaml;
|
||||
|
||||
To test:
|
||||
secrets = {
|
||||
"monitoring-token".owner = "prometheus";
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
sops -d secrets/secrets.yaml
|
||||
Then in services:
|
||||
|
||||
To edit:
|
||||
```nix
|
||||
environment.etc."monitoring/token".source = config.sops.secrets."monitoring-token".path;
|
||||
```
|
||||
|
||||
sops secrets/secrets.yaml
|
||||
---
|
||||
|
||||
### 🧩 Option 2: Reference per-service secrets with explicit `sopsFile`
|
||||
|
||||
```nix
|
||||
# forgejo/sops.nix
|
||||
{
|
||||
sops.secrets = {
|
||||
"admin-password" = {
|
||||
sopsFile = ./../secrets/forgejo/secrets.yaml;
|
||||
owner = "forgejo";
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
[plasmagoat@forgejo:~]$ sudo chmod 400 /etc/sops/age.key && sudo chown root:root /etc/sops/age.key
|
||||
---
|
||||
|
||||
## 🧪 Testing secrets setup
|
||||
|
||||
Check which secrets will be applied:
|
||||
|
||||
```bash
|
||||
nixos-rebuild dry-activate --flake .#my-hostname
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Resources
|
||||
|
||||
* [sops-nix](https://github.com/Mic92/sops-nix)
|
||||
* [Mozilla SOPS](https://github.com/mozilla/sops)
|
||||
* [age encryption](https://github.com/FiloSottile/age)
|
||||
|
|
|
|||
16
nixos/secrets/forgejo/runner-secrets.yml
Normal file
16
nixos/secrets/forgejo/runner-secrets.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
forgejo-runner-registration-token: ENC[AES256_GCM,data:ms0Ouy5GP6rlwkiLXoq31ZPSi9bpDKpNOqzEFATHLHflt+YTIjWuPAVRvKEIEQ==,iv:z2snOwdGq3e7Mxl+CmnoOh8c+ZaA+6lNDdXh2vVLULM=,tag:5ZpELR8K5JBQraMBYdXSuA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1n20y9kmdh324m3tkclvhmyuc7c8hk4w84zsal725adahwl8nzq0s04aq4y
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0d3kzWXd2RElqdnViNGJG
|
||||
NHd5bER1S2dVQUpxOER6Mi9TYlVuOHFhVzNNCnNWZVJzdU1LSG4yR3BNdmFEVzA2
|
||||
bFNzK2cxNG9OcTB6NC8wdDAxcCtDekkKLS0tIExQdWNJQnBmb05RMktoeXF0dDZC
|
||||
M3FyUEswckYrUDdvdmdUYnBqaTZFcncK8aNh8jL8nzYv2vWwhxX4QPed1pjFr2zK
|
||||
9znxO+osZsUNIXySioLBfsA1kfqZCzaASsM2ezfWHKt1nCVQAvbXGA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-06T21:10:54Z"
|
||||
mac: ENC[AES256_GCM,data:cDk2zKgxX01y/X9eQCbLm6OW74nE9HJdtliE6iye3gsDKbM+SqCuU1JTBvEcOAeROLn4svJmlRe3DDTGhrnuNO8tL8qLXKt2oQ0CM+A/3kXBb/jG13ps57fEpD32u/QbK6smVDS0Li+TCHEtfqiLyVat42lgyy9kakgjOll//K0=,iv:K8ly08WGyHLpk07oUwaO7ygEqcriJ3Uq1Ev/FtUcfiY=,tag:8VRCalipvZv0DAOAu9tSlg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
18
nixos/secrets/forgejo/secrets.yml
Normal file
18
nixos/secrets/forgejo/secrets.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
forgejo-admin-password: ENC[AES256_GCM,data:S05b/J9AK2SuIKDSWmtRf72C7V5FwMgZv/o5yxzNXRZEH2eIm18sC6+FEg==,iv:Ig/c4K9Io0S07Ywl4JQtbfxhjXJ7Rvea7+N4KhLUqjc=,tag:rx44tRuAbERBZR45QN6b9A==,type:str]
|
||||
forgejo-db-password: ENC[AES256_GCM,data:5YwRl6HNa1LzJgr73ArllG9s+vWCS7m/s6QQh5YUz8I0anG7GQ==,iv:5ARq3unUy2xbDcAFkucvEhjz/QYC2rYgutEo4T2bw2E=,tag:k7eHKqeA7k6XzksLVcnXRw==,type:str]
|
||||
forgejo-secret-key: ENC[AES256_GCM,data:iserDzOnJkM4HLP4c6rekSFANtRmEXwuCPyfMqo=,iv:3CNqN/DyS4PIl/iOO4JCpWJn3ARlb5KQSCNv5Orx2mo=,tag:q34jEpGrK2EKf0bcBznpQQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1n20y9kmdh324m3tkclvhmyuc7c8hk4w84zsal725adahwl8nzq0s04aq4y
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjeTdJNVExVjB2dzF0dTRu
|
||||
ZEV1RHlvd3VPNUZ1b0FsQW14bHJOUUM5Z1NjCmhudWRoUjd5a3dWSEhwK1dDd0hK
|
||||
N1JUUHhlOVFGVWxwalpvbXJVMlhtcGcKLS0tIFJmRjM4bnJ0TUIyWElaUUd3Y2Zq
|
||||
LzBHRWZXODVDZTE2WnVZOGNQckk4KzAKdm3xnA03JnQnc07yhVVtYkVYS6654Zm1
|
||||
4AcLRSCcWvWrvp26XYVE2UGqU7acfxrTsk07o0nHAQpa5LjgJ4oFKw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-06T18:38:08Z"
|
||||
mac: ENC[AES256_GCM,data:BvpIz6tfVSR3m1l7g4ilUyoTKKqirt+k6tPizxCsAgjztt0IyDCio+cLTln4P1tGSy/frjvbxy1mR3tIDkWn6aDFoYz/gnsbTKHSo/K5Q77jJ3uJffoB3/Wruigojl3EBIQHALicq9xhF8rsH/RKjpWqh+TrQwO+ibbA6ff76cw=,iv:Z0ZwJ9aPpI9MtbsZnvFkW7zsFFOMj5/Gv+tF/mal+yI=,tag:knf01NC/XwgjPUHH+8RpSg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
forgejo-admin-password: ENC[AES256_GCM,data:cLC4JQC8PMF4/aeVBzOROupPLzd7TbYwvudr7yVx4YpLCGSmYXRwJQAoXg==,iv:tG2kL66ZshwZkJodZQ5K8SZKfG1eJYeX9eYsZ7yM7rA=,tag:0roW0M9eUmzejkH6pwN/IA==,type:str]
|
||||
forgejo-db-password: ENC[AES256_GCM,data:0KZJHmNuxpO8TmLNuryipICPTjG9h56+II1Azk+v3fkE5MAb9g==,iv:zb14BvbC2OehCYATgMMoPXv742jjD4v0B12cVhNCWBw=,tag:pnrboj5IvwXYXaZJbZpxTQ==,type:str]
|
||||
hello: ENC[AES256_GCM,data:XkOLnE2Mkunc0zNF1932jOuz1olAwWf56lkqL2dt+h99WoL/vNLfSQ0al8NfEA==,iv:WC2xbB9WmB/khOVjdClFerJ8kjtHjaR/p6rDYaaDZhY=,tag:tT92FNrRm74XoZxoFFXm5g==,type:str]
|
||||
example_key: ENC[AES256_GCM,data:kBk87OXu+qfJjP/2EA==,iv:64WcHaVfQrVCouUCZoHk0z/4ii8U9m61/E9SqLeB3Ms=,tag:MZJ6m7m4+s6BNGhtNs+ZFQ==,type:str]
|
||||
#ENC[AES256_GCM,data:lM4LNQNU2S66a73pUymyUA==,iv:pAHgR+ViSO3Ff2zSaZQcXNGb2r2KH+ZbRd33vpq8ncs=,tag:WTNQCjaESLXTXwcwZePU2A==,type:comment]
|
||||
example_array:
|
||||
- ENC[AES256_GCM,data:Sc1q0Yd3sQ6eOzSwfQA=,iv:L4YBbWWeQZAYROHpiNEtHLDCdcuW+vvEpYhGxD0b62g=,tag:82L6MlHWIMpxKb4B3+Lszg==,type:str]
|
||||
- ENC[AES256_GCM,data:Ud9dpSAcHc8NOq48wQI=,iv:9ERTBUQqKHPUIG57KXbRPMXN37cx+WcxOCDxCWpbE1k=,tag:ftTGF/obIJVZSTodIGoABw==,type:str]
|
||||
example_number: ENC[AES256_GCM,data:1Xvp578L4rjW6g==,iv:82z/MQM586y4WilPZgmisa2C7GTdG0vmIEkyx/aMCXw=,tag:UtNDNKbu0tuhSyu1OQiJJA==,type:float]
|
||||
example_booleans:
|
||||
- ENC[AES256_GCM,data:RkxG/g==,iv:RNZpV/1KRWOazIuHj+SH7r3AmwnRBIUgXgfDplrk5X0=,tag:cKv0dVJGQcluscNspIrPgg==,type:bool]
|
||||
- ENC[AES256_GCM,data:PvghSeY=,iv:xPlMb1LMsg5gAWsCXT3UnMyOfQmSKDKdDrjt+n9+Nqs=,tag:B2aROAGdcupDmoOHAiXeTg==,type:bool]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1n20y9kmdh324m3tkclvhmyuc7c8hk4w84zsal725adahwl8nzq0s04aq4y
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwVElvVXluZCsxK1BiT3c2
|
||||
Zm9kaURNdnZ2Nk9EM0dld2tjdFhrZlFiSEVnCk8zZVpWWlFXS3JYS0Q2WHExLzFU
|
||||
WkFwcDFmR3VrdHFmS2JmVC95TnZIMjQKLS0tIGsyVmp1Sm1uL3FKVWlERUZHdmVw
|
||||
TG9HYXdUdlZNYXJUZng2ejBwbjJoNVkK0ER6mqLdz0hEaovWME4p56tjuYbPIuhb
|
||||
X1smwLmHxgcRboeFU5dyp3wZKBg7ccRPneQKsgJvYb929BesynHr6g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-03T16:03:32Z"
|
||||
mac: ENC[AES256_GCM,data:mLCtH1EPm1cD7KD/fCVO0hrIfG6AOl396kcwdahyr326IRvTneT+6lr+f0XAHSkPXtRsmSCiD9WNhLYAh/kCfsP7tVPKl4X17OHkK9blUJ5JpuqnZJfOQ3PXNitYFvcSUUi1Y1/vIQmDf52oTPlcZgxmTgsQj4MEJIIni7d0SOc=,iv:MhAJ0QAdyHv8BzHIBQ/lZ7zV/MKjcsicbBOw9kwo7Nc=,tag:qrfTfCPxAMvXOm69BMWJ4g==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
11
nixos/secrets/shared-sops.nix
Normal file
11
nixos/secrets/shared-sops.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
sops = {
|
||||
age.keyFile = "/etc/sops/age.key";
|
||||
defaultSopsFile = ./shared/secrets.yml;
|
||||
secrets = {
|
||||
# "monitoring-token".owner = "prometheus";
|
||||
# "ssh-private-key".owner = "root";
|
||||
# "ssh-public-key".owner = "root";
|
||||
};
|
||||
};
|
||||
}
|
||||
16
nixos/secrets/shared/secrets.yml
Normal file
16
nixos/secrets/shared/secrets.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
test: ENC[AES256_GCM,data:a+pmog==,iv:3Ledge90oTzTM8uNFWWIgLafa7/Hhx9WzXRAS3flUZo=,tag:mfWiEWxkZVihuX3S3SY12w==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1n20y9kmdh324m3tkclvhmyuc7c8hk4w84zsal725adahwl8nzq0s04aq4y
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBudWI1RXZBOGFoaGIwWWc2
|
||||
cXdpems4SmY1QjNhOWxHTVBhR1ZPYjdSZUcwClhHb1IzSTBmcFllbWl2UVpabGFo
|
||||
Sm1neTlUVVUwalZUSWVLaVNBUWhUSTAKLS0tIG5yVHBiWGMwMG1OTnBXckh4eXdv
|
||||
MU5UQ29lMmw0ZEJnV09IWEpWc2NYT2MKfl+3cZvgunrgGr7KhjGZOlJ0EKRAiAED
|
||||
pDGr25OcjQgpsg4/LCPPOMsi9Yyi/RICJGyDDINaTLMEQDhIsoOyUQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-06T17:29:59Z"
|
||||
mac: ENC[AES256_GCM,data:nvb3Wc3578e45ob2FyyWlsadVOdErTfJ2Ni5jb06f/WbzDkyJd3lCBRTUIAdyXijT4ErtogHImBjYXzRuCi9xP68mTtaoQb6l8bULKJLdY/yDcMzMyKGZLDxTVW80nLvDrqs5piKBYFWtyFaAEio8fVlA4RIUsyFx/mgcbI3ChA=,iv:9/DmD48MKzBNGSODUr4jqDv17r2o4xgH7TVbpQeuyCU=,tag:1uVui9sVI9SfTlgtqPCLMA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
sops = {
|
||||
defaultSopsFile = ./secrets.yaml;
|
||||
age.keyFile = "/etc/sops/age.key";
|
||||
#secrets."forgejo-admin-password".owner = "forgejo";
|
||||
};
|
||||
}
|
||||
16
nixos/secrets/telegram/secrets.yml
Normal file
16
nixos/secrets/telegram/secrets.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
telegram-alert-bot-token: ENC[AES256_GCM,data:mM1aYhpcCecRUdwkdlBKA+dWOHZEwUvP+m4MIg4n89SzgY8GWw0z1OaIpxfR0w==,iv:tzmCjiYntDYpkO4S0a/tMQkfGQpZjLBiBu4Rs/5RHbc=,tag:5cZDEK474WzXwIW5Jc7S5w==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1n20y9kmdh324m3tkclvhmyuc7c8hk4w84zsal725adahwl8nzq0s04aq4y
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5RE82S05lbHV6aE9qZFhL
|
||||
MTZ4Y1R6cXFSZUFhZHdHbzZ5OWdrOXhwdEZ3CkxzM1NtSjNzeXM5byt1VzVtRHpH
|
||||
Tk9ORUtEZ05FMTgrYVNhU3dKRkFKaHMKLS0tIFlLeWJ1dmJsRWc5SkhDbjdEb0or
|
||||
UHl6emN0My8wcFZWYlZEaElrb2NidjgKlZols9SJQxgaoOdJJxghqlACBcwuFs94
|
||||
IGAOoQVUSFhMCWzyXqAQ/1/VkbWqfiUmvqDa3ulEK2Ri+1F+u3mB1Q==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-06T21:21:32Z"
|
||||
mac: ENC[AES256_GCM,data:YS7BLFXkQ/A5PVLVOyMaqRHGavY0YttFps3njzSiYgBUa4VfPHqMcl2fW5vMec5MwM3GKPFGtrSEZKK1NVqLxUWZrfIF6ugAZ4vhRCyWe1Kze2Zs2S0ia2C3mUdhQR2wb7M7YzohI/e7PDZo0UcrcG3YeEzS5NL7qb0hzFsrGLY=,iv:kqzD06q5X0ZkZ1sIoUQz05b6QRDWQVsPqQYxPP2OAl8=,tag:eexvJspUxpDpwJqU1zEMnA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
Loading…
Add table
Add a link
Reference in a new issue