diff --git a/README.md b/README.md index 3381e7e..6413f87 100644 --- a/README.md +++ b/README.md @@ -499,6 +499,8 @@ PRIVATE_KEY a path to a private SSH key used to decrypt file EDITOR environment variable of editor to use when editing FILE +If STDIN is not interactive, EDITOR will be set to "cp /dev/stdin" + RULES environment variable with path to Nix file specifying recipient public keys. Defaults to './secrets.nix' ``` diff --git a/pkgs/agenix.sh b/pkgs/agenix.sh index c1e89c3..ab959ff 100644 --- a/pkgs/agenix.sh +++ b/pkgs/agenix.sh @@ -114,7 +114,7 @@ function edit { CLEARTEXT_DIR=$(@mktempBin@ -d) CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename "$FILE")" - if [ -f "$FILE" ] + if [ -f "$FILE" ] && [ -t 0 ] then DECRYPT=("${DEFAULT_DECRYPT[@]}") if [[ "${DECRYPT[*]}" != *"--identity"* ]]; then @@ -142,7 +142,7 @@ function edit { warn "$FILE wasn't created." return fi - [ -f "$FILE" ] && [ "$EDITOR" != ":" ] && @diffBin@ -q "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return + [ -f "$FILE" ] && [ "$EDITOR" != ":" ] && [ -f "$CLEARTEXT_FILE.before" ] && @diffBin@ -q "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return ENCRYPT=() while IFS= read -r key diff --git a/test/fixtures/one-way/secrets.nix b/test/fixtures/one-way/secrets.nix new file mode 100644 index 0000000..4e81ad5 --- /dev/null +++ b/test/fixtures/one-way/secrets.nix @@ -0,0 +1,5 @@ +let + system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE"; +in { + "one-way.age".publicKeys = [system1]; +} diff --git a/test/install_ssh_host_keys.nix b/test/install_ssh_host_keys.nix index 72d82ee..fe6ad37 100644 --- a/test/install_ssh_host_keys.nix +++ b/test/install_ssh_host_keys.nix @@ -24,5 +24,9 @@ cp -r "${../example}" /tmp/secrets chmod -R u+rw /tmp/secrets chown -R $USER1_UID:$USERS_GID /tmp/secrets + + cp -r "${./fixtures/one-way}" /tmp/secrets-one-way + chmod -R u+rw /tmp/secrets-one-way + chown -R $USER1_UID:$USERS_GID /tmp/secrets-one-way ''; } diff --git a/test/integration.nix b/test/integration.nix index ff1bbac..0dbe5d0 100644 --- a/test/integration.nix +++ b/test/integration.nix @@ -66,7 +66,8 @@ pkgs.nixosTest { system1.wait_for_file("/tmp/1") assert "${user}" in system1.succeed("cat /tmp/1") - userDo = lambda input : f"sudo -u user1 -- bash -c 'set -eou pipefail; cd /tmp/secrets; {input}'" + userDir = "/tmp/secrets" + userDo = lambda input : f"sudo -u user1 -- bash -c 'set -eou pipefail; cd {userDir}; {input}'" before_hash = system1.succeed(userDo('sha256sum passwordfile-user1.age')).split() print(system1.succeed(userDo('agenix -r -i /home/user1/.ssh/id_ed25519'))) @@ -89,7 +90,15 @@ pkgs.nixosTest { system1.succeed(userDo("rm ~/.ssh/id_rsa")) # user1 can edit a secret by piping in contents - system1.succeed(userDo("echo 'secret1234' | agenix -e passwordfile-user1.age")) + system1.succeed(userDo("echo secret1234 | agenix -e passwordfile-user1.age")) assert "secret1234" in system1.succeed(userDo("EDITOR=cat agenix -e passwordfile-user1.age")) + + # user1 can make a one-way secret, but cannot see the contents, and host can decrypt + userDir = "/tmp/secrets-one-way" + system1.succeed(userDo("echo eye1234 | agenix -e one-way.age")) + system1.fail(userDo("EDITOR=cat agenix -e one-way.age")) + assert "eye1234" in system1.succeed(f"cd {userDir};EDITOR=cat agenix -e one-way.age -i /etc/ssh/ssh_host_ed25519_key") + system1.succeed(userDo("echo nose1234 | agenix -e one-way.age")) + assert "nose1234" in system1.succeed(f"cd {userDir};EDITOR=cat agenix -e one-way.age -i /etc/ssh/ssh_host_ed25519_key") ''; }