From e945c673b8b40ed8dec944a21c3936706647cc4a Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Wed, 24 Jul 2024 08:39:51 -0700 Subject: [PATCH 1/8] Try adding an option to output with armor --- pkgs/agenix.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/agenix.sh b/pkgs/agenix.sh index 628a511..0b08a3a 100644 --- a/pkgs/agenix.sh +++ b/pkgs/agenix.sh @@ -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 From 8f6065756acce9c8eb0f7547d43a3728ac7e2871 Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Mon, 29 Jul 2024 10:28:45 -0700 Subject: [PATCH 2/8] Add armored example --- example/armored-secret.age | 7 +++++++ example/secrets.nix | 4 ++++ 2 files changed, 11 insertions(+) create mode 100644 example/armored-secret.age diff --git a/example/armored-secret.age b/example/armored-secret.age new file mode 100644 index 0000000..0e8bff1 --- /dev/null +++ b/example/armored-secret.age @@ -0,0 +1,7 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFYzWG1FQSBpZkZW +aFpLNnJxc0VUMHRmZ2dZS0pjMGVENnR3OHd5K0RiT1RjRUhibFZBCnN5UG5vUjA3 +SXpsNGtiVUw4T0tIVFo5Wkk5QS9NQlBndzVvektiQ0ozc0kKLS0tIGxyY1Q4dEZ1 +VGZEanJyTFNta2JNRmpZb2FnK2JyS1hSVml1UGdMNWZKQXMKYla+wTXcRedyZoEb +LVWaSx49WoUTU0KBPJg9RArxaeC23GoCDzR/aM/1DvYU +-----END AGE ENCRYPTED FILE----- diff --git a/example/secrets.nix b/example/secrets.nix index 4a43b3b..8ec5e9b 100644 --- a/example/secrets.nix +++ b/example/secrets.nix @@ -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; + }; } From 92af581e8b9bdcab0a213d7d17fb198d546538ca Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Mon, 29 Jul 2024 10:44:12 -0700 Subject: [PATCH 3/8] Add integration test for armored secret --- test/integration.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/integration.nix b/test/integration.nix index 0871ffa..e4f97a5 100644 --- a/test/integration.nix +++ b/test/integration.nix @@ -64,6 +64,10 @@ pkgs.nixosTest { file = ../example/secret2.age; path = "/home/user1/secret2"; }; + secrets.armored-secret = { + file = ../example/armored-secret.age; + path = "/home/user1/armored-secret"; + }; }; }; }; @@ -73,6 +77,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'") @@ -91,8 +96,10 @@ pkgs.nixosTest { system1.wait_for_file("/tmp/1") assert "${user}" in system1.succeed("cat /tmp/1") system1.send_chars("cat /run/user/$(id -u)/agenix/secret2 > /tmp/2\n") + system1.send_chars("cat /run/user/$(id -u)/agenix/armored-secret > /tmp/3\n") system1.wait_for_file("/tmp/2") assert "${secret2}" in system1.succeed("cat /tmp/2") + assert "${armored-secret}" in system1.succeed("cat /tmp/3") assert "${hyphen-secret}" in system1.succeed("cat /run/agenix/leading-hyphen") From 01217f8b39e52ac7a7c5de569b7e176a4b59bca1 Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Mon, 29 Jul 2024 10:50:01 -0700 Subject: [PATCH 4/8] Update docs to include example of armored output --- README.md | 4 ++++ doc/tutorial.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 6e49cc3..1a99029 100644 --- a/README.md +++ b/README.md @@ -332,6 +332,10 @@ 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. diff --git a/doc/tutorial.md b/doc/tutorial.md index 8344121..751afa9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -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/): From d48f920cde5e9336bc307f3d514d2e220b836604 Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Tue, 30 Jul 2024 15:47:45 -0700 Subject: [PATCH 5/8] Run nix fmt on secrets.nix --- example/secrets.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/secrets.nix b/example/secrets.nix index 8ec5e9b..08d8dc3 100644 --- a/example/secrets.nix +++ b/example/secrets.nix @@ -7,7 +7,7 @@ in { "passwordfile-user1.age".publicKeys = [user1 system1]; "-leading-hyphen-filename.age".publicKeys = [user1 system1]; "armored-secret.age" = { - publicKeys = [ user1 ]; + publicKeys = [user1]; armor = true; }; } From 783bf0daf6c3b13e927849039247f213dcf401f8 Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Tue, 30 Jul 2024 15:55:25 -0700 Subject: [PATCH 6/8] Remove path config to use default secret path in test --- test/integration.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration.nix b/test/integration.nix index e4f97a5..29208df 100644 --- a/test/integration.nix +++ b/test/integration.nix @@ -66,7 +66,6 @@ pkgs.nixosTest { }; secrets.armored-secret = { file = ../example/armored-secret.age; - path = "/home/user1/armored-secret"; }; }; }; From d1eefa4de1e66cdf2f340cefd0781b375694f987 Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Tue, 30 Jul 2024 16:03:03 -0700 Subject: [PATCH 7/8] Add wait for file write before assertion --- test/integration.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration.nix b/test/integration.nix index 29208df..0c911f7 100644 --- a/test/integration.nix +++ b/test/integration.nix @@ -95,9 +95,10 @@ pkgs.nixosTest { system1.wait_for_file("/tmp/1") assert "${user}" in system1.succeed("cat /tmp/1") system1.send_chars("cat /run/user/$(id -u)/agenix/secret2 > /tmp/2\n") - system1.send_chars("cat /run/user/$(id -u)/agenix/armored-secret > /tmp/3\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") From da00e1cb898fc8f089e91a37b75a37a3398cc7e2 Mon Sep 17 00:00:00 2001 From: Andrew Lubawy Date: Tue, 30 Jul 2024 16:44:03 -0700 Subject: [PATCH 8/8] Add more description on why armor may be useful --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1a99029..9265a62 100644 --- a/README.md +++ b/README.md @@ -339,6 +339,7 @@ e.g. inside your `flake.nix` file: } ``` 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`: