Merge pull request #276 from dlubawy/feat_add_armor_support

feature: add an option to output secrets in armor
This commit is contained in:
Ryan Mulligan 2025-08-04 08:58:09 -07:00 committed by GitHub
commit 6d194f7522
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 35 additions and 0 deletions

View file

@ -332,9 +332,14 @@ e.g. inside your `flake.nix` file:
{
"secret1.age".publicKeys = [ user1 system1 ];
"secret2.age".publicKeys = users ++ systems;
"armored-secret.age" = {
publicKeys = [ user1 ];
armor = true;
};
}
```
These are the users and systems that will be able to decrypt the `.age` files later with their corresponding private keys.
The armor option may also be supplied here to ensure files are output in Base64 PEM text which is useful for more readable diffs.
You can obtain the public keys from
* your local computer usually in `~/.ssh`, e.g. `~/.ssh/id_ed25519.pub`.
* from a running target machine with `ssh-keyscan`:

View file

@ -25,6 +25,10 @@
{
"secret1.age".publicKeys = [ user1 system1 ];
"secret2.age".publicKeys = users ++ systems;
"armored-secret.age" = {
publicKeys = [ user1 ];
armor = true;
};
}
```
4. Edit secret files (these instructions assume your SSH private key is in ~/.ssh/):

View file

@ -0,0 +1,7 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFYzWG1FQSBpZkZW
aFpLNnJxc0VUMHRmZ2dZS0pjMGVENnR3OHd5K0RiT1RjRUhibFZBCnN5UG5vUjA3
SXpsNGtiVUw4T0tIVFo5Wkk5QS9NQlBndzVvektiQ0ozc0kKLS0tIGxyY1Q4dEZ1
VGZEanJyTFNta2JNRmpZb2FnK2JyS1hSVml1UGdMNWZKQXMKYla+wTXcRedyZoEb
LVWaSx49WoUTU0KBPJg9RArxaeC23GoCDzR/aM/1DvYU
-----END AGE ENCRYPTED FILE-----

View file

@ -6,4 +6,8 @@ in {
"secret2.age".publicKeys = [user1];
"passwordfile-user1.age".publicKeys = [user1 system1];
"-leading-hyphen-filename.age".publicKeys = [user1 system1];
"armored-secret.age" = {
publicKeys = [user1];
armor = true;
};
}

View file

@ -118,6 +118,10 @@ function keys {
(@nixInstantiate@ --json --eval --strict -E "(let rules = import $RULES; in rules.\"$1\".publicKeys)" | @jqBin@ -r .[]) || exit 1
}
function armor {
(@nixInstantiate@ --json --eval --strict -E "(let rules = import $RULES; in (builtins.hasAttr \"armor\" rules.\"$1\" && rules.\"$1\".armor))") || exit 1
}
function decrypt {
FILE=$1
KEYS=$2
@ -148,6 +152,7 @@ function decrypt {
function edit {
FILE=$1
KEYS=$(keys "$FILE") || exit 1
ARMOR=$(armor "$FILE") || exit 1
CLEARTEXT_DIR=$(@mktempBin@ -d)
CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename -- "$FILE")"
@ -169,6 +174,9 @@ function edit {
[ -f "$FILE" ] && [ "$EDITOR" != ":" ] && @diffBin@ -q -- "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return
ENCRYPT=()
if [[ "$ARMOR" == "true" ]]; then
ENCRYPT+=(--armor)
fi
while IFS= read -r key
do
if [ -n "$key" ]; then

View file

@ -64,6 +64,9 @@ pkgs.nixosTest {
file = ../example/secret2.age;
path = "/home/user1/secret2";
};
secrets.armored-secret = {
file = ../example/armored-secret.age;
};
};
};
};
@ -73,6 +76,7 @@ pkgs.nixosTest {
password = "password1234";
secret2 = "world!";
hyphen-secret = "filename started with hyphen";
armored-secret = "Hello World!";
in ''
system1.wait_for_unit("multi-user.target")
system1.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
@ -93,6 +97,9 @@ pkgs.nixosTest {
system1.send_chars("cat /run/user/$(id -u)/agenix/secret2 > /tmp/2\n")
system1.wait_for_file("/tmp/2")
assert "${secret2}" in system1.succeed("cat /tmp/2")
system1.send_chars("cat /run/user/$(id -u)/agenix/armored-secret > /tmp/3\n")
system1.wait_for_file("/tmp/3")
assert "${armored-secret}" in system1.succeed("cat /tmp/3")
assert "${hyphen-secret}" in system1.succeed("cat /run/agenix/leading-hyphen")