Skip to content

Commit 5b728a3

Browse files
MartinNikovPetarKirov
authored andcommitted
feat(modules): Add secrets as nixosModules
1 parent 4bde465 commit 5b728a3

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

modules/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
./shard-split
88
./random-alerts
99
./host-info.nix
10+
./secrets.nix
1011
];
1112
}

modules/secrets.nix

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

0 commit comments

Comments
 (0)