Skip to content

Commit

Permalink
feat: add configuration option to allow using age instead of rage
Browse files Browse the repository at this point in the history
  • Loading branch information
oddlama committed Feb 25, 2024
1 parent e02a57e commit aeed929
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 25 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,19 @@ which are also generated automatically:
}
```
## Using age instead of rage
If you don't want to use rage for some reason, you can specify a compatible
alternative tool in your top-level configure call:
```nix
agenix-rekey = agenix-rekey.configure {
userFlake = self;
nodes = self.nixosConfigurations;
agePackage = p: p.age;
};
```
## How does it work?
The central problem is that rekeying secrets on-the-fly while building your system
Expand Down
16 changes: 8 additions & 8 deletions apps/edit.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ pkgs, ... } @ inputs: let
{pkgs, ...} @ inputs: let
inherit
(pkgs.lib)
concatStringsSep
Expand All @@ -14,8 +14,8 @@
(import ../nix/lib.nix inputs)
userFlakeDir
mergedSecrets
rageMasterEncrypt
rageMasterDecrypt
ageMasterEncrypt
ageMasterDecrypt
;

relativeToFlake = filePath: let
Expand Down Expand Up @@ -76,9 +76,9 @@ in
case "''${#POSITIONAL_ARGS[@]}" in
0)
${optionalString (builtins.length validRelativeSecretPaths == 0) ''
die "No relevant secret definitions were found for any host. Pass a filename to create a new secret regardless of whether it is already used."
break
''}
die "No relevant secret definitions were found for any host. Pass a filename to create a new secret regardless of whether it is already used."
break
''}
FILE=$(echo ${escapeShellArg (concatStringsSep "\n" validRelativeSecretPaths)} \
| ${pkgs.fzf}/bin/fzf --tiebreak=end --bind=tab:down,btab:up,change:top --height='~50%' --tac --cycle --layout=reverse) \
|| die "No file selected. Aborting."
Expand Down Expand Up @@ -113,7 +113,7 @@ in
if [[ -e "$FILE" ]]; then
[[ -z ''${INFILE+x} ]] || die "Refusing to overwrite existing file when using --input"
${rageMasterDecrypt} -o "$CLEARTEXT_FILE" "$FILE" \
${ageMasterDecrypt} -o "$CLEARTEXT_FILE" "$FILE" \
|| die "Failed to decrypt file. Aborting."
else
mkdir -p "$(dirname "$FILE")" \
Expand Down Expand Up @@ -143,7 +143,7 @@ in
exit 0
fi
${rageMasterEncrypt} -o "$ENCRYPTED_FILE" "$CLEARTEXT_FILE" \
${ageMasterEncrypt} -o "$ENCRYPTED_FILE" "$CLEARTEXT_FILE" \
|| die "Failed to (re)encrypt edited file, original is left unchanged."
cp --no-preserve=all "$ENCRYPTED_FILE" "$FILE" # cp instead of mv preserves original attributes and permissions
Expand Down
8 changes: 4 additions & 4 deletions apps/generate.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
inherit
(import ../nix/lib.nix inputs)
userFlakeDir
rageMasterDecrypt
rageMasterEncrypt
ageMasterDecrypt
ageMasterEncrypt
;

relativeToFlake = filePath: let
Expand Down Expand Up @@ -62,7 +62,7 @@
inherit (pkgs) lib;
file = sourceFile;
name = secretName;
decrypt = rageMasterDecrypt;
decrypt = ageMasterDecrypt;
deps = flip map secret.generator.dependencies (dep:
assert assertMsg (dep.generator != null)
"The given dependency with rekeyFile=${dep.rekeyFile} is a secret without a generator."; {
Expand Down Expand Up @@ -118,7 +118,7 @@
${contextSecret.script}
) || die "Generator exited with status $?."
${rageMasterEncrypt} -o ${escapeShellArg contextSecret.sourceFile} <<< "$content" \
${ageMasterEncrypt} -o ${escapeShellArg contextSecret.sourceFile} <<< "$content" \
|| die "Failed to generate or encrypt secret."
if [[ "$ADD_TO_GIT" == true ]]; then
Expand Down
8 changes: 4 additions & 4 deletions apps/rekey.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

inherit
(import ../nix/lib.nix inputs)
rageHostEncrypt
rageMasterDecrypt
ageHostEncrypt
ageMasterDecrypt
;

# The derivation containing the resulting rekeyed secrets for
Expand Down Expand Up @@ -54,7 +54,7 @@
rm ${secretOut}.tmp &>/dev/null || true
echo " Rekeying "${escapeShellArg hostName}":"${escapeShellArg secretName}""
if ! decrypt ${escapeShellArg secret.rekeyFile} ${escapeShellArg secretName} ${escapeShellArg hostName} \
| ${rageHostEncrypt hostCfg} -o ${secretOut}.tmp; then
| ${ageHostEncrypt hostCfg} -o ${secretOut}.tmp; then
echo "Failed to re-encrypt ${secret.rekeyFile} for ${hostName}!" >&2
fi
# Make sure to only create the result file if the rekeying was actually successful.
Expand Down Expand Up @@ -171,7 +171,7 @@ in
# Outer loop, allows us to retry the command
while true; do
# Try command
if ${rageMasterDecrypt} "$secret_file"; then
if ${ageMasterDecrypt} "$secret_file"; then
return
fi
Expand Down
13 changes: 9 additions & 4 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,29 @@
nodes,
# The package sets to use. pkgs.${system} must yield an initialized nixpkgs package set
pkgs ? self.pkgs,
# A function that returns the age package given a package set. Use
# this to override which tools is used for encrypting / decrypting.
# Defaults to rage (pkgs.rage). We only guarantee compatibility for
# pkgs.age and pkgs.rage.
agePackage ? (p: p.rage),
}:
flake-utils.lib.eachDefaultSystem (system: {
apps = pkgs.${system}.lib.genAttrs allApps (app:
import ./apps/${app}.nix {
inherit nodes userFlake;
inherit nodes userFlake agePackage;
pkgs = pkgs.${system};
});
});

# XXX: deprecated, scheduled for removal in 2024. Use the package instead of
# XXX: deprecated, scheduled for removal in late 2024. Use the package instead of
# defining apps. This is just a compatibility wrapper that defines apps with
# the same interface as before.
defineApps = argsOrSelf: pkgs: nodes:
pkgs.lib.warn ''
The `agenix-rekey.defineApps self pkgs nodes` function is deprecated and will
be removed in 2024. The new approach will unclutter your flake's app definitions
be removed late 2024. The new approach will unclutter your flake's app definitions
and provide a hermetic entrypoint for agenix-rekey, which can be accessed more
egonomically via a new CLI wrapper 'agenix'. Alternatively via you can still run
egonomically via a new CLI wrapper 'agenix'. Alternatively you can still run
the scripts directly from your flake using `nix run .#agenix-rekey.apps.$system.<app>`,
in case you don't want to use the wrapper.
Expand Down
13 changes: 8 additions & 5 deletions nix/lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
userFlake,
pkgs,
nodes,
agePackage,
...
}: let
inherit
Expand All @@ -11,6 +12,7 @@
concatStringsSep
escapeShellArg
filter
getExe
mapAttrsToList
removeSuffix
substring
Expand All @@ -30,9 +32,10 @@
then "-R ${escapeShellArg x}"
else "-r ${escapeShellArg x}";

ageProgram = getExe (agePackage pkgs);
# Collect all paths to enabled age plugins
envPath = ''PATH="$PATH"${concatMapStrings (x: ":${escapeShellArg x}/bin") mergedAgePlugins}'';
# The identities which can decrypt secrets need to be passed to rage
# The identities which can decrypt secrets need to be passed to age
masterIdentityArgs = concatMapStrings (x: "-i ${escapeShellArg x} ") mergedMasterIdentities;
# Extra recipients for master encrypted secrets
extraEncryptionPubkeys = concatStringsSep " " (map pubkeyOpt mergedExtraEncryptionPubkeys);
Expand All @@ -41,9 +44,9 @@ in {
inherit mergedSecrets;

# Premade shell commands to encrypt and decrypt secrets
rageMasterEncrypt = "${envPath} ${pkgs.rage}/bin/rage -e ${masterIdentityArgs} ${extraEncryptionPubkeys}";
rageMasterDecrypt = "${envPath} ${pkgs.rage}/bin/rage -d ${masterIdentityArgs}";
rageHostEncrypt = hostAttrs: let
ageMasterEncrypt = "${envPath} ${ageProgram} -e ${masterIdentityArgs} ${extraEncryptionPubkeys}";
ageMasterDecrypt = "${envPath} ${ageProgram} -d ${masterIdentityArgs}";
ageHostEncrypt = hostAttrs: let
hostPubkey = removeSuffix "\n" hostAttrs.config.age.rekey.hostPubkey;
in "${envPath} ${pkgs.rage}/bin/rage -e ${pubkeyOpt hostPubkey}";
in "${envPath} ${ageProgram} -e ${pubkeyOpt hostPubkey}";
}

0 comments on commit aeed929

Please sign in to comment.