Skip to content

Commit c2a71c8

Browse files
authored
Merge pull request #158 from whentze/decrypt-only
add -d/--decrypt option to decrypt a file to stdout
2 parents 2d735d6 + 9cf1967 commit c2a71c8

3 files changed

Lines changed: 45 additions & 5 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,13 +483,16 @@ Overriding `age.secretsMountPoint` example:
483483
### agenix CLI reference
484484

485485
```
486+
agenix - edit and rekey age secret files
487+
486488
agenix -e FILE [-i PRIVATE_KEY]
487489
agenix -r [-i PRIVATE_KEY]
488490
489491
options:
490492
-h, --help show help
491493
-e, --edit FILE edits FILE using $EDITOR
492494
-r, --rekey re-encrypts all secrets with specified recipients
495+
-d, --decrypt FILE decrypts FILE to STDOUT
493496
-i, --identity identity to use when decrypting
494497
-v, --verbose verbose output
495498
@@ -499,6 +502,8 @@ PRIVATE_KEY a path to a private SSH key used to decrypt file
499502
500503
EDITOR environment variable of editor to use when editing FILE
501504
505+
If STDIN is not interactive, EDITOR will be set to "cp /dev/stdin"
506+
502507
RULES environment variable with path to Nix file specifying recipient public keys.
503508
Defaults to './secrets.nix'
504509
```

pkgs/agenix.sh

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ function show_help () {
1414
# shellcheck disable=SC2016
1515
echo '-e, --edit FILE edits FILE using $EDITOR'
1616
echo '-r, --rekey re-encrypts all secrets with specified recipients'
17+
echo '-d, --decrypt FILE decrypts FILE to STDOUT'
1718
echo '-i, --identity identity to use when decrypting'
1819
echo '-v, --verbose verbose output'
1920
echo ' '
@@ -45,6 +46,7 @@ function err() {
4546
test $# -eq 0 && (show_help && exit 1)
4647

4748
REKEY=0
49+
DECRYPT_ONLY=0
4850
DEFAULT_DECRYPT=(--decrypt)
4951

5052
while test $# -gt 0; do
@@ -77,6 +79,17 @@ while test $# -gt 0; do
7779
shift
7880
REKEY=1
7981
;;
82+
-d|--decrypt)
83+
shift
84+
DECRYPT_ONLY=1
85+
if test $# -gt 0; then
86+
export FILE=$1
87+
else
88+
echo "no FILE specified"
89+
exit 1
90+
fi
91+
shift
92+
;;
8093
-v|--verbose)
8194
shift
8295
set -x
@@ -89,7 +102,6 @@ while test $# -gt 0; do
89102
done
90103

91104
RULES=${RULES:-./secrets.nix}
92-
93105
function cleanup {
94106
if [ -n "${CLEARTEXT_DIR+x}" ]
95107
then
@@ -102,10 +114,13 @@ function cleanup {
102114
}
103115
trap "cleanup" 0 2 3 15
104116

105-
function edit {
106-
FILE=$1
107-
KEYS=$( (@nixInstantiate@ --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" rules.\"$FILE\".publicKeys)" | @sedBin@ 's/"//g' | @sedBin@ 's/\\n/\n/g') | @sedBin@ '/^$/d' || exit 1)
117+
function keys {
118+
(@nixInstantiate@ --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" rules.\"$1\".publicKeys)" | @sedBin@ 's/"//g' | @sedBin@ 's/\\n/\n/g') | @sedBin@ '/^$/d' || exit 1
119+
}
108120

121+
function decrypt {
122+
FILE=$1
123+
KEYS=$2
109124
if [ -z "$KEYS" ]
110125
then
111126
err "There is no rule for $FILE in $RULES."
@@ -132,6 +147,12 @@ function edit {
132147
@ageBin@ "${DECRYPT[@]}" || exit 1
133148
cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
134149
fi
150+
}
151+
152+
function edit {
153+
FILE=$1
154+
KEYS=$(keys "$FILE") || exit 1
155+
decrypt "$FILE" "$KEYS" || exit 1
135156

136157
[ -t 0 ] || EDITOR='cp /dev/stdin'
137158

@@ -160,6 +181,14 @@ function edit {
160181
mv -f "$REENCRYPTED_FILE" "$1"
161182
}
162183

184+
function decrypt_only {
185+
FILE=$1
186+
KEYS=$(keys "$FILE") || exit 1
187+
decrypt "$FILE" "$KEYS"
188+
printf "%s" "$(<"${CLEARTEXT_FILE}")"
189+
cleanup
190+
}
191+
163192
function rekey {
164193
FILES=$( (@nixInstantiate@ --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" (builtins.attrNames rules))" | @sedBin@ 's/"//g' | @sedBin@ 's/\\n/\n/g') || exit 1)
165194

@@ -172,4 +201,5 @@ function rekey {
172201
}
173202

174203
[ $REKEY -eq 1 ] && rekey && exit 0
204+
[ $DECRYPT_ONLY -eq 1 ] && decrypt_only "${FILE}" && exit 0
175205
edit "$FILE" && cleanup && exit 0

test/integration.nix

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ pkgs.nixosTest {
9090
9191
# user1 can edit a secret by piping in contents
9292
system1.succeed(userDo("echo 'secret1234' | agenix -e passwordfile-user1.age"))
93-
assert "secret1234" in system1.succeed(userDo("EDITOR=cat agenix -e passwordfile-user1.age"))
93+
94+
# and get it back out via --decrypt
95+
assert "secret1234" in system1.succeed(userDo("agenix -d passwordfile-user1.age"))
96+
97+
# finally, the plain text should not linger around anywhere in the filesystem.
98+
system1.fail("grep -r secret1234 /tmp")
9499
'';
95100
}

0 commit comments

Comments
 (0)