167 lines
6.2 KiB
Nix
167 lines
6.2 KiB
Nix
{ core, self, store, ... } @ libs:
|
|
{ config, pkgs, ... } @ env:
|
|
let
|
|
inherit(core) list path set string type;
|
|
gpg = path.import ./gpg.nix libs env;
|
|
|
|
checkSecrets
|
|
= set.mapToListConcatted
|
|
(
|
|
name:
|
|
value:
|
|
let
|
|
expect
|
|
= entry:
|
|
if value.${entry} != null
|
|
then
|
|
[]
|
|
else
|
|
[ "Secret `${name}` is of type `${value.type}`, but is missing `${entry}`." ];
|
|
extra
|
|
= entry:
|
|
if value.${entry} != null
|
|
then
|
|
[ "Secret `${name}` is of type `${value.type}`, but `${entry}` was set." ]
|
|
else
|
|
[];
|
|
in
|
|
if value.type or null != null
|
|
then
|
|
{
|
|
decrypt = (expect "encryptedFile") ++ (extra "variables");
|
|
generateEnvFile = (extra "encryptedFile") ++ (expect "variables");
|
|
generateToken = (extra "encryptedFile") ++ (extra "variables");
|
|
}.${value.type} or [ "Unknown/unimplemented type `${value.type}`." ]
|
|
else if value == null then [ "${name} is null, missing generateToken?" ]
|
|
else if list.isInstanceOf value then [ "${name} is a list, missing generateEnvFile?" ]
|
|
else [ "${name} is invalid: ${type.getPrimitive value}" ]
|
|
);
|
|
|
|
decryptFiles
|
|
= { homedir, vaultBasePath } @ args:
|
|
set.mapToListConcatted
|
|
(
|
|
name:
|
|
{ group, owner, encryptedFile, type, ... }:
|
|
let
|
|
fileName = "${vaultBasePath}/${name}";
|
|
in
|
|
if type == "decrypt"
|
|
then
|
|
(gpg.decrypt args encryptedFile fileName)
|
|
++ (setPermissions { inherit fileName group owner; })
|
|
else
|
|
[]
|
|
);
|
|
|
|
generateEnvFiles
|
|
= { vaultBasePath, ... }:
|
|
set.mapToListConcatted
|
|
(
|
|
name:
|
|
{ group, owner, type, variables, ... }:
|
|
if type == "generateEnvFile"
|
|
then
|
|
let
|
|
fileName = "${vaultBasePath}/${name}";
|
|
in
|
|
[ ''echo -n "" > "${fileName}"'' ]
|
|
++ (
|
|
list.map
|
|
(
|
|
variable:
|
|
''echo "_${variable}_=\"$(${utils}/cat "${vaultBasePath}/${variable}")\"" >> "${fileName}"''
|
|
)
|
|
variables
|
|
)
|
|
++ (setPermissions { inherit fileName group owner; })
|
|
else
|
|
[]
|
|
);
|
|
|
|
generateTokens
|
|
= { vaultBasePath, ... }:
|
|
set.mapToListConcatted
|
|
(
|
|
name:
|
|
{ generator, group, length, owner, type, ... }:
|
|
if type == "generateToken"
|
|
then
|
|
let
|
|
generator' = if generator != null then generator else "[:graph:]";
|
|
length' = if length != null then string length else "32";
|
|
getRandom = "${utils}/cat /dev/urandom";
|
|
filterChars = "${utils}/tr --delete --complement \"${generator'}\"";
|
|
takeChars = "${utils}/head --bytes \"${length'}\"";
|
|
fileName = "${vaultBasePath}/${name}";
|
|
generate = ''${getRandom} | ${filterChars} | ${takeChars} > "${fileName}"'';
|
|
in
|
|
[ generate ]
|
|
++ (setPermissions { inherit fileName group owner; })
|
|
else
|
|
[]
|
|
);
|
|
|
|
setPermissions
|
|
= { fileName, group, owner }:
|
|
let
|
|
ifGroup = value: if group != null then value else "";
|
|
owner' = if owner != null then owner else "root";
|
|
in
|
|
[
|
|
''${utils}/chmod --changes --recursive u=r,g=${ifGroup "r"},o= "${fileName}"''
|
|
''${utils}/chown --changes --recursive "${owner'}:${ifGroup group}" "${fileName}"''
|
|
];
|
|
|
|
utils = "${pkgs.coreutils}/bin";
|
|
in
|
|
{
|
|
homedir ? "/tmp/keyring",
|
|
key,
|
|
secrets,
|
|
vault
|
|
}:
|
|
let
|
|
args
|
|
= {
|
|
inherit homedir;
|
|
vaultBasePath = vault;
|
|
};
|
|
daemon
|
|
= pkgs.writeShellScript "initVault.sh"
|
|
(
|
|
string.concatLines
|
|
(
|
|
[
|
|
''set -e''
|
|
''echo "initialise ${vault}..."''
|
|
''${utils}/install --mode u=rwx,g=x,o=x --directory "${vault}/"''
|
|
]
|
|
# ++ [ ''echo "enable smart card..."'' ]
|
|
# ++ ( gpg.enableSmartCard args )
|
|
++ [ ''echo "import vault key ${key}..."'' ]
|
|
++ ( gpg.importKey args key )
|
|
++ [ ''echo "decrypt files..."'' ]
|
|
++ ( decryptFiles args secrets )
|
|
++ [ ''echo "generate tokens..."'' ]
|
|
++ ( generateTokens args secrets )
|
|
++ [ ''echo "generate environment files..."'' ]
|
|
++ ( generateEnvFiles args secrets )
|
|
++ [
|
|
''echo "...done"''
|
|
''exit 0''
|
|
]
|
|
)
|
|
);
|
|
in
|
|
{
|
|
errors = checkSecrets secrets;
|
|
vault
|
|
= ''
|
|
${utils}/rm --recursive --force ${homedir}
|
|
${utils}/install --mode u=rwx,g=,o= --directory ${homedir}
|
|
${gpg.startAgent { inherit daemon homedir; }}
|
|
${utils}/rm --recursive ${homedir}
|
|
'';
|
|
}
|