2022-12-04 13:45:43 +00:00
|
|
|
{
|
|
|
|
lib,
|
|
|
|
pkgs,
|
2022-12-04 16:10:00 +00:00
|
|
|
config,
|
2022-12-04 13:45:43 +00:00
|
|
|
...
|
2023-09-11 23:22:18 +01:00
|
|
|
}: let
|
|
|
|
inherit (lib.modules) mkIf mkMerge;
|
|
|
|
inherit (lib.options) mkOption;
|
|
|
|
inherit (lib) types;
|
|
|
|
inherit (pkgs) writeShellApplication;
|
|
|
|
|
2022-11-15 13:42:28 +00:00
|
|
|
cfg = config.services.secrets;
|
2023-09-11 23:22:18 +01:00
|
|
|
|
|
|
|
secretsLib = import ./secrets-lib/lib.nix {
|
|
|
|
inherit lib pkgs;
|
|
|
|
};
|
2022-11-15 13:42:28 +00:00
|
|
|
in {
|
|
|
|
options = {
|
|
|
|
services.secrets = {
|
|
|
|
enable = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
debug = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
createSecretsDir = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
secretsDirUser = mkOption {
|
2023-09-11 23:22:18 +01:00
|
|
|
type = types.either types.str types.int;
|
2022-11-15 13:42:28 +00:00
|
|
|
default = "root";
|
|
|
|
};
|
|
|
|
|
|
|
|
secretsDirGroup = mkOption {
|
2023-09-11 23:22:18 +01:00
|
|
|
type = types.either types.str types.int;
|
2022-11-15 13:42:28 +00:00
|
|
|
default = "root";
|
|
|
|
};
|
|
|
|
|
|
|
|
secretsDir = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "/secrets";
|
|
|
|
};
|
|
|
|
|
2023-09-14 13:54:56 +01:00
|
|
|
requiredVaultPaths = mkOption {
|
|
|
|
type = types.listOf (types.oneOf [
|
|
|
|
types.str
|
|
|
|
(types.submodule {
|
|
|
|
options = {
|
|
|
|
path = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
};
|
|
|
|
capabilities = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
default = ["read" "list"];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
})
|
|
|
|
]);
|
|
|
|
default = [];
|
|
|
|
description = "default vault paths as API path, not kv2 path";
|
|
|
|
};
|
|
|
|
|
2022-11-15 13:42:28 +00:00
|
|
|
vaultURL = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "https://vault.owo.monster";
|
|
|
|
description = "default Vault URL, can be overrided with env variables";
|
|
|
|
};
|
|
|
|
|
|
|
|
extraFunctions = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = "extra bash functions to add to top of script";
|
|
|
|
};
|
|
|
|
|
2023-09-11 23:22:18 +01:00
|
|
|
uidMap = mkOption {
|
|
|
|
type = types.attrsOf types.int;
|
|
|
|
default = {};
|
|
|
|
description = "optional mapping of users to user IDs; required for SYSROOT when user isn't available on host";
|
|
|
|
};
|
|
|
|
|
|
|
|
gidMap = mkOption {
|
|
|
|
type = types.attrsOf types.int;
|
|
|
|
default = {};
|
|
|
|
description = "optional mapping of groups to group IDs; required for SYSROOT when group isn't available on host";
|
|
|
|
};
|
|
|
|
|
|
|
|
packages = mkOption {
|
2022-11-15 13:42:28 +00:00
|
|
|
type = types.listOf types.package;
|
2023-09-13 16:21:54 +01:00
|
|
|
default = [];
|
2023-09-11 23:22:18 +01:00
|
|
|
description = "packages for script";
|
2022-11-15 13:42:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
secrets = mkOption {
|
2022-12-04 16:10:00 +00:00
|
|
|
type = types.attrsOf (types.submodule ({name, ...}: {
|
2022-11-15 13:42:28 +00:00
|
|
|
options = {
|
|
|
|
user = mkOption {
|
2023-09-11 23:22:18 +01:00
|
|
|
type = types.either types.str types.int;
|
2022-11-15 13:42:28 +00:00
|
|
|
default = "root";
|
|
|
|
};
|
|
|
|
group = mkOption {
|
2023-09-11 23:22:18 +01:00
|
|
|
type = types.either types.str types.int;
|
2022-11-15 13:42:28 +00:00
|
|
|
default = "root";
|
|
|
|
};
|
|
|
|
permissions = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "660";
|
|
|
|
};
|
|
|
|
path = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "${cfg.secretsDir}/${name}";
|
|
|
|
};
|
|
|
|
|
|
|
|
fetchScript = mkOption {
|
2023-09-11 23:22:18 +01:00
|
|
|
type = types.nullOr types.lines;
|
|
|
|
default = null;
|
2022-11-15 13:42:28 +00:00
|
|
|
description = ''
|
2023-09-11 23:22:18 +01:00
|
|
|
script used to fetch secrets, $secretFile is secret.path
|
2022-11-15 13:42:28 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
checkScript = mkOption {
|
|
|
|
type = types.nullOr types.lines;
|
|
|
|
default = null;
|
|
|
|
description = ''
|
|
|
|
script used to check contents of secret file, set LOCAL_FAIL to true on failure
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
manual = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "should the secret be manually deployed";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkMerge [
|
|
|
|
(mkIf (cfg.enable) (let
|
2023-09-11 23:22:18 +01:00
|
|
|
scripts = secretsLib.genScripts cfg;
|
2023-09-13 16:21:54 +01:00
|
|
|
defaultPackages = with pkgs; [vault-bin jq];
|
2022-11-15 13:42:28 +00:00
|
|
|
in {
|
|
|
|
environment.systemPackages = [
|
2023-09-11 23:22:18 +01:00
|
|
|
(writeShellApplication {
|
2022-11-15 13:42:28 +00:00
|
|
|
name = "secrets-init";
|
2023-09-11 23:22:18 +01:00
|
|
|
runtimeInputs = defaultPackages ++ cfg.packages;
|
|
|
|
text = scripts.initScript;
|
|
|
|
})
|
|
|
|
(writeShellApplication {
|
|
|
|
name = "secrets-check";
|
|
|
|
runtimeInputs = defaultPackages ++ cfg.packages;
|
|
|
|
text = scripts.checkScript;
|
2022-11-15 13:42:28 +00:00
|
|
|
})
|
|
|
|
];
|
|
|
|
}))
|
|
|
|
|
|
|
|
(mkIf (cfg.enable && cfg.createSecretsDir) {
|
|
|
|
systemd.tmpfiles.rules = [
|
2023-09-11 23:22:18 +01:00
|
|
|
"d ${cfg.secretsDir} - ${toString cfg.secretsDirUser} ${toString cfg.secretsDirGroup}"
|
2022-11-15 13:42:28 +00:00
|
|
|
];
|
|
|
|
})
|
|
|
|
];
|
|
|
|
}
|