Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,39 @@ Enter passphrase for identity file "key.age":

Passphrase-protected identity files are not necessary for most use cases, where access to the encrypted identity file implies access to the whole system. However, they can be useful if the identity file is stored remotely.

### Storing identities in a password manager

Rather than keeping an identity file on disk, it can be kept in a password manager and piped in with `-i -`. Use a name scoped to the purpose of the key, since age identities are cheap to generate and can't be rotated.
Comment on lines +282 to +284

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you advocate for password encrypting the identity before storing on a 1password or other system? If those systems are compromised your identies are plain text and exposed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good point. I added a paragraph making the trust model explicit (the identity is only as safe as the password manager entry), plus an example of storing a passphrase-protected, armored identity instead (age-keygen | age -p -a), which works with -i - and prompts for the passphrase. I also noted that the SOPS temp file holds the key unencrypted on disk.


```console
$ op read "op://Personal/git-repo-secrets-age-identity/password" | age -d -i - secrets.txt.age
```

The same pattern works with other password manager CLIs, such as `bw get notes ...` (Bitwarden) or `pass show ...` (pass).

Note that this way the identity is only as safe as the password manager: anyone who can read the entry, such as through a compromised account or an unlocked session, can decrypt every file encrypted to it. If that's not acceptable, store a [passphrase-protected identity](#passphrase-protected-key-files) instead, armored so that it can be saved as text. age will prompt for the passphrase when it reads it from standard input.

```console
$ age-keygen | age -p -a
Enter passphrase (leave empty to autogenerate a secure one):
Confirm passphrase:
-----BEGIN AGE ENCRYPTED FILE-----
[...]
-----END AGE ENCRYPTED FILE-----
$ op read "op://Personal/git-repo-secrets-age-identity/password" | age -d -i - secrets.txt.age
Enter passphrase for identity file "-":
```

Tools that require an identity file path, such as [SOPS](https://github.com/getsops/sops), need the key to be materialized to a temporary file instead. The identity is then stored unencrypted on disk until the file is removed, so keep its lifetime as short as possible.

```console
$ SOPS_AGE_KEY_FILE=$(mktemp) && trap 'rm -f "$SOPS_AGE_KEY_FILE"' EXIT
$ chmod 600 "$SOPS_AGE_KEY_FILE"
$ op read "op://Personal/git-repo-secrets-age-identity/password" > "$SOPS_AGE_KEY_FILE"
$ export SOPS_AGE_KEY_FILE
$ sops -d secrets.enc.yaml
```

### SSH keys

As a convenience feature, age also supports encrypting to `ssh-rsa` and `ssh-ed25519` SSH public keys, and decrypting with the respective private key file. (`ssh-agent` is not supported.)
Expand Down
Loading