Warning
This is currently an experimental plugin.
age-plugin-vault is a plugin for the age encryption tool that uses HashiCorp Vault's Transit secrets engine to encrypt and decrypt the age file key. This means that a transit key is used to encrypt the file key and is also used as the recipient and identity. This has the advantage that the wrap key (i.e., the transit key) never leaves the vault server and is also unknown to the user. Another advantage is that the transit key can be easily rotated.
- Go (1.20+ recommended)
- A running HashiCorp Vault server with the
transitengine enabled - A Vault token available in
~/.vault-token, or on Linux a keyring reference in~/.vault-token
Note: The Vault client uses
vault.DefaultConfig(). If Vault is not athttp://127.0.0.1:8200, set Vault environment variableVAULT_ADDRaccordingly.Linux keyring usage example: write
keyring:<scope>:<description>into~/.vault-tokenand store the token in the corresponding keyring scope. Supported scopes areprocess,session, anduser.Example:
keyring:process:my-vault-tokenreads the vault token from the current process keyring entry with descriptionmy-vault-token.
From the project root:
# Clone repo
git clone git@github.com:stsch9/age-plugin-vault.git
cd age-plugin-vault
# Build the plugin binary
go build -o age-plugin-vault ./cmd/age-plugin-vault/main.goEnsure that age-plugin-vault is stored in a directory that is included in the PATH variable.
- Enable the Transit engine (if not already enabled):
vault secrets enable transit- Create a transit key:
vault write -f transit/keys/my-keyname type=<KEY_TYP>Only use key types that support encryption.
- Ensure the Vault token you use has permissions to call
transit/encrypt/my-keynameandtransit/decrypt/my-keyname.
The name of the vault key is used as the age identity.
Generate an identity string (key name) that can be used with age for encryption/decryption:
# Generates an identity string for 'my-keyname'
./age-plugin-vault -generate my-keynameThe output is an age identity (bech32-encoded) for this plugin, e.g. AGE-PLUGIN-VAULT-....
- Encrypt (use the identity):
age -e -i <identity-file-or-string> -o secret.txt.age secret.txt- Decrypt (provide the identity string or file):
age -d -i <identity-file-or-string> -o secret.txt secret.txt.ageTbd
go test ./...The vault key name is used as the identity, and the recipient stanza always contains
-> age-encryption.org/vault vault-recipientWould it make more sense to use the vault key name in the recipient stanza?
Contributions, issues and feature requests are welcome. Please open an issue or a pull request.
This project is licensed under the MIT License. See LICENSE for details.
If you need help setting up Vault or integrating the plugin with age, please open an issue. 💬