Skip to content

Commit

Permalink
cmd/age: passphrase optionnaly supplied from an environment variable
Browse files Browse the repository at this point in the history
The passphrase is now read from the AGE_PASSPHRASE environment
variable, as an alternative to being requested interactively.

This enables the following usage patterns:
- automation of the encryption, without having to manage
an additional private key file
- provide a less error prone way of supplying a passphrase.
Copy-pasting to an echo-less prompt, for example, is often hazardous
on some platforms.
  • Loading branch information
wj committed Aug 15, 2023
1 parent 6ad4560 commit a3f72c8
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
17 changes: 13 additions & 4 deletions cmd/age/age.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,12 @@ func main() {
}
}

func passphrasePromptForEncryption() (string, error) {
func passphraseForEncryption() (string, error) {
passFromEnv := os.Getenv("AGE_PASSPHRASE")
if passFromEnv != "" {
return passFromEnv, nil
}

pass, err := readSecret("Enter passphrase (leave empty to autogenerate a secure one):")
if err != nil {
return "", fmt.Errorf("could not read passphrase: %v", err)
Expand Down Expand Up @@ -359,7 +364,7 @@ func encryptNotPass(recs, files []string, identities identityFlags, in io.Reader
}

func encryptPass(in io.Reader, out io.Writer, armor bool) {
pass, err := passphrasePromptForEncryption()
pass, err := passphraseForEncryption()
if err != nil {
errorf("%v", err)
}
Expand Down Expand Up @@ -440,7 +445,7 @@ func decryptPass(in io.Reader, out io.Writer) {
identities := []age.Identity{
// If there is an scrypt recipient (it will have to be the only one and)
// this identity will be invoked.
&LazyScryptIdentity{passphrasePromptForDecryption},
&LazyScryptIdentity{passphraseForDecryption},
}

decrypt(identities, in, out)
Expand Down Expand Up @@ -470,7 +475,11 @@ func decrypt(identities []age.Identity, in io.Reader, out io.Writer) {
}
}

func passphrasePromptForDecryption() (string, error) {
func passphraseForDecryption() (string, error) {
passFromEnv := os.Getenv("AGE_PASSPHRASE")
if passFromEnv != "" {
return passFromEnv, nil
}
pass, err := readSecret("Enter passphrase:")
if err != nil {
return "", fmt.Errorf("could not read passphrase: %v", err)
Expand Down
14 changes: 9 additions & 5 deletions doc/age.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ optional and defaults to standard input. Only a single <INPUT> file may be
specified. If `-o` is not specified, <OUTPUT> defaults to standard output.

If `-p`/`--passphrase` is specified, the file is encrypted with a passphrase
requested interactively. Otherwise, it's encrypted to one or more
requested either interactively, or through the AGE_PASSPHRASE environment
variable. Otherwise, it's encrypted to one or more
[RECIPIENTS][RECIPIENTS AND IDENTITIES] specified with `-r`/`--recipient` or
`-R`/`--recipients-file`. Every recipient can decrypt the file.

In `-d`/`--decrypt` mode, passphrase-encrypted files are detected automatically
and the passphrase is requested interactively. Otherwise, one or more
[IDENTITIES][RECIPIENTS AND IDENTITIES] specified with `-i`/`--identity` are
used to decrypt the file.
and the passphrase is requested either interactively, or read from the
AGE_PASSPHRASE environment variable.
Otherwise, one or more [IDENTITIES][RECIPIENTS AND IDENTITIES] specified
with `-i`/`--identity` are used to decrypt the file.

`age` encrypted files are binary and not malleable, with around 200 bytes of
overhead per recipient, plus 16 bytes every 64KiB of plaintext.
Expand Down Expand Up @@ -62,8 +64,10 @@ overhead per recipient, plus 16 bytes every 64KiB of plaintext.
and the file can be decrypted by all provided recipients independently.

* `-p`, `--passphrase`:
Encrypt with a passphrase, requested interactively from the terminal.
Encrypt with a passphrase, requested either:
- interactively from the terminal.
`age` will offer to auto-generate a secure passphrase.
- through the AGE_PASSPHRASE environment variable.

This option can't be used with other recipient flags.

Expand Down

0 comments on commit a3f72c8

Please sign in to comment.