Created
May 25, 2021 01:36
-
-
Save ryantm/385279275fa740f9fa7dec2973d5d90f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ config, lib, pkgs, ... }: | |
with lib; | |
let | |
cfg = config.age; | |
# we need at least rage 0.5.0 to support ssh keys | |
rage = | |
if lib.versionOlder pkgs.rage.version "0.5.0" | |
then pkgs.callPackage ../pkgs/rage.nix { } | |
else pkgs.rage; | |
ageBin = "${rage}/bin/rage"; | |
users = config.users.users; | |
identities = builtins.concatStringsSep " " (map (path: "-i ${path}") cfg.sshKeyPaths); | |
installSecret = secretType: '' | |
set -x # DEBUG | |
echo "decrypting ${secretType.file} to ${secretType.path}..." | |
TMP_FILE="${secretType.path}.tmp" | |
mkdir -p $(dirname ${secretType.path}) | |
ls -la $(dirname ${secretType.path}) # DEBUG | |
( | |
umask u=r,g=,o= | |
LANG=${config.i18n.defaultLocale} ${ageBin} --decrypt ${identities} -o "$TMP_FILE" "${secretType.file}" | |
) | |
chmod ${secretType.mode} "$TMP_FILE" | |
chown ${secretType.owner}:${secretType.group} "$TMP_FILE" | |
mv -f "$TMP_FILE" '${secretType.path}' | |
''; | |
isRootSecret = st: (st.owner == "root" || st.owner == "0") && (st.group == "root" || st.group == "0"); | |
isNotRootSecret = st: !(isRootSecret st); | |
rootOwnedSecrets = builtins.filter isRootSecret (builtins.attrValues cfg.secrets); | |
installRootOwnedSecrets = builtins.concatStringsSep "\n" ([ "echo '[agenix] decrypting root secrets...'" ] ++ (map installSecret rootOwnedSecrets)); | |
nonRootSecrets = builtins.filter isNotRootSecret (builtins.attrValues cfg.secrets); | |
installNonRootSecrets = builtins.concatStringsSep "\n" ([ "echo '[agenix] decrypting non-root secrets...'" ] ++ (map installSecret nonRootSecrets)); | |
secretType = types.submodule ({ config, ... }: { | |
options = { | |
name = mkOption { | |
type = types.str; | |
default = config._module.args.name; | |
description = '' | |
Name of the file used in /run/secrets | |
''; | |
}; | |
file = mkOption { | |
type = types.path; | |
description = '' | |
Age file the secret is loaded from. | |
''; | |
}; | |
path = mkOption { | |
type = types.str; | |
default = "/run/secrets/${config.name}"; | |
description = '' | |
Path where the decrypted secret is installed. | |
''; | |
}; | |
mode = mkOption { | |
type = types.str; | |
default = "0400"; | |
description = '' | |
Permissions mode of the in octal. | |
''; | |
}; | |
owner = mkOption { | |
type = types.str; | |
default = "0"; | |
description = '' | |
User of the file. | |
''; | |
}; | |
group = mkOption { | |
type = types.str; | |
default = users.${config.owner}.group or "0"; | |
description = '' | |
Group of the file. | |
''; | |
}; | |
}; | |
}); | |
in | |
{ | |
options.age = { | |
secrets = mkOption { | |
type = types.attrsOf secretType; | |
default = { }; | |
description = '' | |
Attrset of secrets. | |
''; | |
}; | |
sshKeyPaths = mkOption { | |
type = types.listOf types.path; | |
default = | |
if config.services.openssh.enable then | |
map (e: e.path) (lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys) | |
else [ ]; | |
description = '' | |
Path to SSH keys to be used as identities in age decryption. | |
''; | |
}; | |
}; | |
config = mkIf (cfg.secrets != { }) { | |
assertions = [{ | |
assertion = cfg.sshKeyPaths != [ ]; | |
message = "age.sshKeyPaths must be set."; | |
}]; | |
# Secrets with root owner and group can be installed before users | |
# exist. This allows user password files to be encrypted. | |
system.activationScripts.agenixRoot.text = installRootOwnedSecrets; | |
system.activationScripts.users.deps = [ "agenixRoot" ]; | |
# Other secrets need to wait for users and groups to exist. | |
system.activationScripts.agenix = stringAfter [ "users" "groups" ] installNonRootSecrets; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment