Skip to content

Commit

Permalink
modules/age: add secrets change detection
Browse files Browse the repository at this point in the history
  • Loading branch information
erikarvstedt committed Jan 9, 2023
1 parent 7f6e175 commit 87d3318
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions modules/age.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@ let
users = config.users.users;

newGeneration = ''
_agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)"
(( ++_agenix_generation ))
_agenix_last_generation=$(basename "$(readlink ${cfg.secretsDir})" || true)
if [[ $_agenix_last_generation == ${secretsHash} ]]; then
_agenix_generation=
else
_agenix_generation="${secretsHash}"
fi
if [[ $_agenix_generation ]]; then
echo "[agenix] creating new generation in ${cfg.secretsMountPoint}/$_agenix_generation"
mkdir -p "${cfg.secretsMountPoint}"
chmod 0751 "${cfg.secretsMountPoint}"
grep -q "${cfg.secretsMountPoint} ramfs" /proc/mounts || mount -t ramfs none "${cfg.secretsMountPoint}" -o nodev,nosuid,mode=0751
mkdir -p "${cfg.secretsMountPoint}/$_agenix_generation"
chmod 0751 "${cfg.secretsMountPoint}/$_agenix_generation"
fi
'';

identities = builtins.concatStringsSep " " (map (path: "-i ${path}") cfg.identityPaths);
Expand Down Expand Up @@ -60,18 +66,16 @@ let
'') cfg.identityPaths;

cleanupAndLink = ''
_agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)"
(( ++_agenix_generation ))
echo "[agenix] symlinking new secrets to ${cfg.secretsDir} (generation $_agenix_generation)..."
ln -sfn "${cfg.secretsMountPoint}/$_agenix_generation" ${cfg.secretsDir}
(( _agenix_generation > 1 )) && {
echo "[agenix] removing old secrets (generation $(( _agenix_generation - 1 )))..."
rm -rf "${cfg.secretsMountPoint}/$(( _agenix_generation - 1 ))"
[[ $_agenix_last_generation ]] && {
echo "[agenix] removing old secrets (generation $_agenix_last_generation)..."
rm -rf "${cfg.secretsMountPoint}/$_agenix_last_generation"
}
'';

installSecrets = builtins.concatStringsSep "\n" (
installSecrets = mkInstallScript (
[ "echo '[agenix] decrypting secrets...'" ]
++ testIdentities
++ (map installSecret (builtins.attrValues cfg.secrets))
Expand All @@ -89,11 +93,25 @@ let
chown :keys "${cfg.secretsMountPoint}" "${cfg.secretsMountPoint}/$_agenix_generation"
'';

chownSecrets = builtins.concatStringsSep "\n" (
chownSecrets = mkInstallScript (
[ "echo '[agenix] chowning...'" ]
++ [ chownMountPoint ]
++ (map chownSecret (builtins.attrValues cfg.secrets)));

mkInstallScript = strings: ''
[[ ! $_agenix_generation ]] || {
${builtins.concatStringsSep "\n" strings}
}
'';

secretsHash = let
sha256 = builtins.hashString "sha256" (builtins.concatStringsSep " " (
map (secret: cfg.secrets.${secret}.path) (attrNames cfg.secrets)
));
in
# Truncate to 128 bits (base16) to increase readability
substring 0 32 sha256;

secretType = types.submodule ({ config, ... }: {
options = {
name = mkOption {
Expand All @@ -104,7 +122,13 @@ let
'';
};
file = mkOption {
type = types.path;
type = mkOptionType {
name = "nix-path";
descriptionClass = "noun";
check = builtins.isPath;
merge = mergeEqualOption;
};

description = ''
Age file the secret is loaded from.
'';
Expand Down

0 comments on commit 87d3318

Please sign in to comment.