Initial commit

This commit is contained in:
2026-04-17 00:27:22 +02:00
commit 9af07bedff
80 changed files with 5389 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
keys:
- &admin age122w85pqj508ukv0rd388mahecgfckmpgnsgz0zcyec37ljae2epsdnvxpl
- &orion age1l49tm85prcpm4q8e0hxxetv08jqv3gfty3pvzte956dng4h0xaeq0he5yd
creation_rules:
- path_regex: secrets.yaml$
key_groups:
- age:
- *admin
- *orion

View File

@@ -0,0 +1,32 @@
radicale-pass: ENC[AES256_GCM,data:3CpCnSibLWeZUJRBMuc=,iv:3J9x4ejcsYXCjRRGP5lOex+9EG8STLsbJ7FWesRpLIk=,tag:Pg1jIlnr2enuTsCvvWRWjg==,type:str]
university-calendar-url: ENC[AES256_GCM,data:oGP1BdF3YxdRRr061LaC4HaaiPXoyZq7ZALqU+cv8wb2GgYT+jgshgx9LRjM3jsIjPXolkG5bCZi46r/rpEk3mWSskQ3YnCXcwM1BN+PPVapdtQgkRSWriAOUXPnRpaZzpMs5WaJTnkOrJJqfAoy+jGIE0Nhul/CRw5tOeRkwPbDxfA/dY9MT80ciHWHscHb1w9R,iv:1JqN80OnrIjOl4LGmk99LsJMmoT3hGjlCet6mYeRb5o=,tag:9GhVQIa1BXAEjdOxswHH/A==,type:str]
ssh-config-orion: ENC[AES256_GCM,data:8vrbtuHCLlMDtMAfnJuf+DcWmPZwFFpyGag8l32JAFUMmWyEEEvDctNDHNahw8fiQzwN0+9atjY=,iv:UKWqjZ4D3+McASovEaE5jt4TAkmlwR26chFvWblgc1k=,tag:oZJKwLDPQEbfa4CPHn9lVQ==,type:str]
orion-ip: ENC[AES256_GCM,data:S6fpCWnD8dvchvrHlEo=,iv:72+oRxHUEJ7imJ+sWjGbG+TUrSqYL8hbyHl3ChwFYwA=,tag:Rj6msje87+Ve+M6kcZd4Jw==,type:str]
hashed-password-kiri: ENC[AES256_GCM,data:xubN5stH4RPlHYl+Jzcu2BCepz3Hra3TxjiSspktzjgpEWrU79h3NbcPMrYC0MSjsv3oaWio/S7nBV3Tes3WBlI9EC9vq+6tyTVPynUqpB7c9CvvYSmqc9bAHOnIOBb+gP2RR6JB395UoQ==,iv:uN83RNTfCJdBDhFhywV5NbVBp4xcptqzoKVAoAnaiQk=,tag:x9yufiPdSJwBADT6QymExA==,type:str]
gemini-api-key-neovim: ENC[AES256_GCM,data:B8FeFt45FsU3aagyLDKXiwmx0mRrsw4C8RQ3EWXwZ+YfWLMvwJad,iv:1HqBD6vc07Ke/PMYXfHqFrWDGw/UMjiiBjLRN33/xHI=,tag:czcrYGbJFi41rYtIPM4qTQ==,type:str]
booklore-db-pass: ENC[AES256_GCM,data:dlPGXQ24itEaBRJSJ9WOogWCdF3atFQ2ZtlLGyGq8Tin5OmSZI6lZUzSE+femBW5SBTIlKQvzHEPCs9MT5tyMIqetzGLm+mMN3FDW7si684Cuv9z9Uq5gjAZWh14KQMWYPI=,iv:oLnqu2EDFBVcBpswVRXXeF617YolPxOUx9CscHRRn/8=,tag:Si6gF1EXhcHalk11D3Exlw==,type:str]
deluge-auth-file: ENC[AES256_GCM,data:uJME7CAC5OOJZLPdu9MNkg8ZDZZ64Wsytg==,iv:5l4eTSbdSKtOwjXGr7D1Teud5TON1+lcjWeI8W4bCuQ=,tag:ND8+cOUef1fwAGjmvWXEUQ==,type:str]
sops:
age:
- recipient: age122w85pqj508ukv0rd388mahecgfckmpgnsgz0zcyec37ljae2epsdnvxpl
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMQXRVTlRjZDRMWksvc200
T2lUN0d6eXZJZ2k2aXZHVUY4M2hSWFZEeVNBCkkxMTZQbGlZRFRHeW9wSFdwbXc0
bHdWYVZucGlXTkYvSFRWNW83RUNCRDAKLS0tIG9ha2psQVhwY3NMS21mOUNkeEFx
M3p6Nm9mY2RNVUp3ZW5KUGwvdm1rV2sKFygdzZgjTuG2JMzMnGuyE6qv4IvjHsIu
Sv0PpSC9wgJQhoOCHUQVaPzn/Zv7llFlU3GBRqk8FLCj/IVaYVoc1g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1l49tm85prcpm4q8e0hxxetv08jqv3gfty3pvzte956dng4h0xaeq0he5yd
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaWXVtMHBpMWtGOU03OGlH
NW9WYVNkYWxBcEErUy91dW5VSWtBRGcxY2dNCm5ZTDhBT1U1TjZrdnBKVi85QkRD
QkQwSDBock5MVGRwMmFkcjFxaXFZR0EKLS0tIHovWC9TREFxSjdTcjVTM3VnczJX
aW8vM0IwQ243TnNPdnlkeHE4bTFLR00KaJhbOxdbIUJSzn4lOt2OO1HOTNaOoiSE
+pKjsYZZQBdcYFPREjffEL+oiyxHwoLi95noHad9AGmygLqwboUkWg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-09T12:12:17Z"
mac: ENC[AES256_GCM,data:pEbPRbwpYbOibyFgysUVcGvZGTqEuvuLJizMzxvIgpn0B/jAsysRsi9aZd8HN6jOypRq0AaVVDmT6gDM6PBWXMPEx3Mlh83sW5omyc6+i2eN2HfB1xXr46PG23WJ+k3LTbuPjTW00U8S3uvhr4ouaZ7c9ZlJBPevgoQECYflYZE=,iv:ppdSkpBLmCEGIEioc5HeuiVAmvgkC2g4WIkWWSh9fL0=,tag:f2xn3GeZulFnG4Dqqh3gYA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.12.1

81
modules/secrets/sops.nix Normal file
View File

@@ -0,0 +1,81 @@
{ den, inputs, lib, ... }:
let
sopsReadersGroup = "sops-users";
in
{
den.ctx.host.includes = [
(den.lib.perHost (
{ host, ... }:
let
missingAdminUsers = lib.filter (userName: !(builtins.hasAttr userName host.users)) host.sopsAdminKeyUsers;
adminKeyDir = if host.sopsAdminKeyPath == null then null else builtins.dirOf host.sopsAdminKeyPath;
in
{
nixos = {
imports = [ inputs.sops-nix.nixosModules.sops ];
sops = {
defaultSopsFile = ./secrets.yaml;
age =
if host.sopsHostSshKeyPath != null then
{
sshKeyPaths = [ host.sopsHostSshKeyPath ];
}
else
{
keyFile = host.sopsAdminKeyPath;
};
};
users.groups = lib.optionalAttrs (host.sopsAdminKeyUsers != [ ]) {
${sopsReadersGroup} = { };
};
users.users = lib.genAttrs host.sopsAdminKeyUsers (_: {
extraGroups = [ sopsReadersGroup ];
});
systemd.tmpfiles.rules = lib.optionals (adminKeyDir != null) [
"d ${adminKeyDir} 0750 root ${sopsReadersGroup} -"
];
assertions = [
{
assertion = host.sopsAdminKeyUsers == [ ] || host.sopsAdminKeyPath != null;
message = "Hosts with sopsAdminKeyUsers must set sopsAdminKeyPath.";
}
{
assertion = missingAdminUsers == [ ];
message =
"All sopsAdminKeyUsers must exist on the host. Missing: "
+ lib.concatStringsSep ", " missingAdminUsers;
}
];
};
}
))
];
den.ctx.user.includes = [
(den.lib.perUser (
{ host, user, ... }:
if builtins.elem user.userName host.sopsAdminKeyUsers then
{
homeManager =
{ pkgs, ... }:
{
imports = [ inputs.sops-nix.homeManagerModules.sops ];
sops = {
defaultSopsFile = ./secrets.yaml;
age.keyFile = host.sopsAdminKeyPath;
};
home.packages = [ pkgs.sops ];
};
}
else
{ }
))
];
}