mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 23:00:39 +02:00
feat(kanidm): run provision script and secret manipulator
This commit is contained in:
parent
6063da387b
commit
31602de07d
2 changed files with 86 additions and 6 deletions
13
README.md
13
README.md
|
@ -142,8 +142,21 @@ openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
|
||||||
|
|
||||||
groups.grafana-access = {};
|
groups.grafana-access = {};
|
||||||
groups.grafana-server-admins = {};
|
groups.grafana-server-admins = {};
|
||||||
|
groups.grafana-admins = {};
|
||||||
|
groups.grafana-editors = {};
|
||||||
|
|
||||||
systems.oauth2.grafana = {
|
systems.oauth2.grafana = {
|
||||||
|
displayName = "Grafana";
|
||||||
|
originUrl = "https://grafana.${personalDomain}";
|
||||||
|
basicSecretFile = pkgs.writeText "bs" "verygoodsecret";
|
||||||
|
scopeMaps = {
|
||||||
|
grafana-access = ["openid" "email" "profile"];
|
||||||
|
};
|
||||||
|
supplementaryScopeMaps = {
|
||||||
|
grafana-server-admins = ["server_admin"];
|
||||||
|
grafana-admins = ["admin"];
|
||||||
|
grafana-editors = ["editor"];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,36 @@
|
||||||
default = script;
|
default = script;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = ''
|
provisionScript = pkgs.writeShellScrip "post-start-provision" ''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# TODO login
|
# Wait for the kanidm server to come online
|
||||||
|
count=0
|
||||||
|
while ! test -e /run/kanidmd/sock; do
|
||||||
|
if [ "$count" -eq 300 ]; then
|
||||||
|
echo "Tried for 30 seconds, giving up..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! kill -0 "$MAINPID"; then
|
||||||
|
echo "Main server died, giving up..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep 0.1
|
||||||
|
count=$((count++))
|
||||||
|
done
|
||||||
|
|
||||||
|
# If this is the first start, we login this time by recovering the admin account
|
||||||
|
# and force a restart afterwards to rewrite the password.
|
||||||
|
if test -e "$STATE_DIRECTORY/.first_startup"; then
|
||||||
|
KANIDM_PASSWORD="$(${cfg.package}/bin/kanidmd recover-account admin)"
|
||||||
|
needs_rewrite=1
|
||||||
|
rm -f "$STATE_DIRECTORY/.first_startup"
|
||||||
|
else
|
||||||
|
# Login using the admin password
|
||||||
|
KANIDM_PASSWORD="$(< ${escapeShellArg cfg.provision.adminPasswordFile})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
${cfg.package}/bin/kanidm login --name admin <<< "$KANIDM_PASSWORD"
|
||||||
|
|
||||||
known_groups=$(kanidm group list --output=json)
|
known_groups=$(kanidm group list --output=json)
|
||||||
function group_exists() {
|
function group_exists() {
|
||||||
|
@ -62,18 +88,39 @@
|
||||||
${concatMapStrings (x: x._script) (attrValues cfg.provision.groups)}
|
${concatMapStrings (x: x._script) (attrValues cfg.provision.groups)}
|
||||||
${concatMapStrings (x: x._script) (attrValues cfg.provision.persons)}
|
${concatMapStrings (x: x._script) (attrValues cfg.provision.persons)}
|
||||||
${concatMapStrings (x: x._script) (attrValues cfg.provision.systems.oauth2)}
|
${concatMapStrings (x: x._script) (attrValues cfg.provision.systems.oauth2)}
|
||||||
|
|
||||||
|
if [[ "''${needs_rewrite-0}" == 1 ]]; then
|
||||||
|
echo "Queueing service restart to rewrite secrets"
|
||||||
|
touch "$STATE_DIRECTORY/.needs_restart"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
restarterScript = pkgs.writeShellScript "post-start-restarter" ''
|
||||||
|
set -euo pipefail
|
||||||
|
if test -e "$STATE_DIRECTORY/.needs_restart"; then
|
||||||
|
rm -f "$STATE_DIRECTORY/.needs_restart"
|
||||||
|
systemctl restart kanidm
|
||||||
|
fi
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
options.services.kanidm.provision = {
|
options.services.kanidm.provision = {
|
||||||
enable = mkEnableOption "provisioning of systems (oauth2), groups and users";
|
enable = mkEnableOption "provisioning of systems (oauth2), groups and users";
|
||||||
|
|
||||||
|
adminPasswordFile = mkOption {
|
||||||
|
description = "Path to a file containing the admin password for kanidm. Do NOT use a file from the nix store here!";
|
||||||
|
example = "/run/secrets/kanidm-admin-password";
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
|
||||||
persons = mkOption {
|
persons = mkOption {
|
||||||
description = "Provisioning of kanidm persons";
|
description = "Provisioning of kanidm persons";
|
||||||
default = {};
|
default = {};
|
||||||
type = types.attrsOf (types.submodule (personSubmod: let
|
type = types.attrsOf (types.submodule (personSubmod: let
|
||||||
inherit (personSubmod.module._args) name;
|
inherit (personSubmod.module._args) name;
|
||||||
updateArgs =
|
updateArgs =
|
||||||
(optionals (personSubmod.config.legalName != null) ["--legalname" personSubmod.config.legalName])
|
["--displayname" personSubmod.config.displayName]
|
||||||
|
++ optionals (personSubmod.config.legalName != null)
|
||||||
|
["--legalname" personSubmod.config.legalName]
|
||||||
# mail addresses
|
# mail addresses
|
||||||
++ concatMap (addr: ["--mail" addr]) personSubmod.config.mailAddresses;
|
++ concatMap (addr: ["--mail" addr]) personSubmod.config.mailAddresses;
|
||||||
in {
|
in {
|
||||||
|
@ -86,8 +133,6 @@ in {
|
||||||
kanidm person create ${escapeShellArg name} \
|
kanidm person create ${escapeShellArg name} \
|
||||||
${escapeShellArg personSubmod.config.displayName}
|
${escapeShellArg personSubmod.config.displayName}
|
||||||
fi
|
fi
|
||||||
''
|
|
||||||
+ optionalString (updateArgs != []) ''
|
|
||||||
kanidm person update ${escapeShellArg name} ${escapeShellArgs updateArgs}
|
kanidm person update ${escapeShellArg name} ${escapeShellArgs updateArgs}
|
||||||
''
|
''
|
||||||
+ flip concatMapStrings personSubmod.config.groups (group: ''
|
+ flip concatMapStrings personSubmod.config.groups (group: ''
|
||||||
|
@ -173,6 +218,7 @@ in {
|
||||||
${escapeShellArg name} \
|
${escapeShellArg name} \
|
||||||
${escapeShellArg oauth2Submod.config.displayName} \
|
${escapeShellArg oauth2Submod.config.displayName} \
|
||||||
${escapeShellArg oauth2Submod.config.originUrl}
|
${escapeShellArg oauth2Submod.config.originUrl}
|
||||||
|
needs_rewrite=1
|
||||||
fi
|
fi
|
||||||
''
|
''
|
||||||
+ concatLines (flip mapAttrsToList oauth2Submod.config.scopeMaps (group: scopes: ''
|
+ concatLines (flip mapAttrsToList oauth2Submod.config.scopeMaps (group: scopes: ''
|
||||||
|
@ -227,7 +273,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = mkIf (cfg.enableServer && cfg.provision.enable) {
|
||||||
assertions =
|
assertions =
|
||||||
flip mapAttrsToList cfg.provision.persons (person: personCfg: let
|
flip mapAttrsToList cfg.provision.persons (person: personCfg: let
|
||||||
unknownGroups = subtractLists (attrNames cfg.provision.groups) personCfg.groups;
|
unknownGroups = subtractLists (attrNames cfg.provision.groups) personCfg.groups;
|
||||||
|
@ -249,5 +295,26 @@ in {
|
||||||
message = "kanidm: provision.systems.oauth2.${oauth2}.supplementaryScopeMaps: Refers to unknown groups: ${unknownGroups}";
|
message = "kanidm: provision.systems.oauth2.${oauth2}.supplementaryScopeMaps: Refers to unknown groups: ${unknownGroups}";
|
||||||
})
|
})
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
systemd.services.kanidm = {
|
||||||
|
serviceConfig.ExecStartPost =
|
||||||
|
[provisioningScript]
|
||||||
|
++
|
||||||
|
# Only the restarter runs with elevated privileges
|
||||||
|
optional (cfg.provision.systems.oauth2 != {}) "+${restarterScript}";
|
||||||
|
|
||||||
|
preStart = let
|
||||||
|
mappingsJson = pkgs.writeText "mappings.json" (builtins.toJSON {
|
||||||
|
account_secrets.admin = cfg.provision.adminPasswordFile;
|
||||||
|
oauth2_basic_secrets = mapAttrs (_: x: v.basicSecretFile) cfg.provision.systems.oauth2;
|
||||||
|
});
|
||||||
|
in ''
|
||||||
|
if ! test -e ${escapeShellArg cfg.serverSettings.db_path}; then
|
||||||
|
touch "$STATE_DIRECTORY/.first_startup"
|
||||||
|
else
|
||||||
|
${getExe pkgs.kanidm-secret-manipulator} ${escapeShellArg cfg.serverSettings.db_path} ${tokenMappings}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue