ready for runners

This commit is contained in:
plasmagoat 2025-06-06 23:32:17 +02:00
parent fc9971ddc9
commit 7dd5043b5d
49 changed files with 2569 additions and 1085 deletions

59
nixos/secrets/HOWTO.md Normal file
View 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})"
'';
```

View file

@ -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 — youll 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 — its 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)

View 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

View 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

View file

@ -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

View 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";
};
};
}

View 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

View file

@ -1,8 +0,0 @@
{ config, lib, ... }:
{
sops = {
defaultSopsFile = ./secrets.yaml;
age.keyFile = "/etc/sops/age.key";
#secrets."forgejo-admin-password".owner = "forgejo";
};
}

View 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