Skip to content

Commit fcaeb10

Browse files
committed
feat(modules): Add secrets as nixosModules
1 parent 261a658 commit fcaeb10

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

modules/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
./folder-size-metrics
77
./shard-split
88
./host-info.nix
9+
./secrets.nix
910
];
1011
}

modules/secrets.nix

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
{withSystem, ...}: {
2+
flake.nixosModules.mcl-secrets = {
3+
config,
4+
options,
5+
lib,
6+
dirs,
7+
...
8+
}: let
9+
eachServiceCfg = config.mcl.secrets.services;
10+
isDebugVM = config.mcl.host-info.isDebugVM;
11+
12+
sshKey = config.mcl.host-info.sshKey;
13+
14+
ageSecretOpts =
15+
builtins.head
16+
(builtins.head
17+
options.age.secrets.type.nestedTypes.elemType.getSubModules)
18+
.imports;
19+
20+
secretDir = let
21+
machineConfigPath = config.mcl.host-info.configPath;
22+
machineSecretDir = machineConfigPath + "/secrets";
23+
vmConfig = dirs.modules + "/default-vm-config";
24+
vmSecretDir = vmConfig + "/secrets";
25+
in
26+
if isDebugVM
27+
then vmSecretDir
28+
else machineSecretDir;
29+
in {
30+
options.mcl.secrets = with lib; {
31+
services = mkOption {
32+
type = types.attrsOf (types.submodule ({config, ...}: let
33+
serviceName = config._module.args.name;
34+
in {
35+
options = {
36+
encryptedSecretDir = mkOption {
37+
type = types.path;
38+
default = secretDir;
39+
};
40+
secrets = mkOption {
41+
default = {};
42+
type = types.attrsOf (types.submoduleWith {
43+
modules = [
44+
ageSecretOpts
45+
({name, ...}: let
46+
secretName = name;
47+
in {
48+
config = {
49+
name = "${serviceName}/${secretName}";
50+
file =
51+
lib.mkDefault (config.encryptedSecretDir + "/${serviceName}/${secretName}.age");
52+
};
53+
})
54+
];
55+
});
56+
};
57+
extraKeys = mkOption {
58+
type = types.listOf types.str;
59+
default = [];
60+
example = ["ssh-ed25519 AAAAC3Nza" "ssh-ed25519 AAAACSNss"];
61+
description = "Extra keys which can decrypt the secrets.";
62+
};
63+
nix-file = mkOption {
64+
default =
65+
if (pathIsRegularFile (config.encryptedSecretDir + "/${serviceName}/secrets.nix"))
66+
then config.encryptedSecretDir + "/${serviceName}/secrets.nix"
67+
else
68+
builtins.toFile "${serviceName}-secrets.nix" ''
69+
let
70+
hostKey = ["${sshKey}"];
71+
extraKeys = ["${concatStringsSep "\"\"" config.extraKeys}"];
72+
in {
73+
${concatMapStringsSep "\n"
74+
(n: "\"${n}.age\".publicKeys = hostKey ++ extraKeys;")
75+
(builtins.attrNames config.secrets)}
76+
}
77+
'';
78+
type = types.path;
79+
};
80+
};
81+
}));
82+
default = {};
83+
example = {
84+
service1.secrets.secretA = {};
85+
service1.secrets.secretB = {};
86+
service2.secrets.secretC = {};
87+
cachix-deploy.secrets.token = {
88+
path = "/etc/cachix-agent.token";
89+
};
90+
};
91+
description = mdDoc "Per-service attrset of encryptedSecretDir and secrets";
92+
};
93+
};
94+
95+
config = lib.mkIf (eachServiceCfg != {}) {
96+
age.secrets = lib.pipe eachServiceCfg [
97+
(lib.mapAttrsToList (serviceName: service:
98+
lib.mapAttrsToList (
99+
secretName: config:
100+
lib.nameValuePair "${serviceName}/${secretName}" config
101+
)
102+
service.secrets))
103+
lib.concatLists
104+
lib.listToAttrs
105+
];
106+
};
107+
};
108+
}

0 commit comments

Comments
 (0)