Skip to content

Commit 0ef9dcd

Browse files
committed
feat(modules): Add secrets as nixosModules
1 parent 042d906 commit 0ef9dcd

File tree

2 files changed

+123
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)