Introduction
Bring your own key (BYOK) functionality, which was introduced in Vault 1.11.0, allows users to import keys that were generated outside of Vault into the Transit secrets engine. The two API methods of import
& import_version
are what's related and these will be exemplified in this article.
Execution
In order to import a key it needs to be a cipher-text that's a base64 encoded value and with the correct order as detailed below.
An internal and private Go-based tool called transit-byok can be used to generate properly formatted values that may serve to demonstrate the expected import format. The tool handles the fetching of a wrapping key, generating an ephemeral key, wrapping the source key with the ephemeral key, encrypting the ephemeral key with the wrapping key, and finally calling the import or import_version transit endpoints.
These steps below involve the exporting of keys from one transit secret engine called a transit and then importing it into another transit secret engine called transit_import.
1) Pre-requisite: GO installed & available.
2) Set enviroment variable: GOROOT, GOPATH or PATH to include project path.
3) Download & Unzip: transit-byok.zip.
4) Extracted folder will contain: go.sum, go.mod, main.go, README & LICENSE
5) Run the command: go mod download in the folder where go.mod resides.
6) Build using: go build . which will generate the tool binaries.
7) We'll use the term byok to refer to the built utility.
8) Set Vault variables: export VAULT_ADDR & export VAULT_TOKEN
9) Enable a transit secret engine:
vault secrets enable transit
10) Create an encryption key ring named 'test':
vault write -f transit/keys/test
11) Export encryption key ring:
vault read /transit/export/encryption-key/test exportable="true"
# Key Value
# --- -----
# keys map[1:1vn2s11+fE4mXMtmmbBqTSLY8M0Wc83yRsCpz9eiR4k=]
# name test
# type aes256-gcm96
12) With the environment variables set & encryption key exported, run the import sub-command
# Here we enable one more secret engine so that we can import the key in it
vault secrets enable -path=transit_import transit
./byok import transit_import/keys/test-key-imp 1vn2s11+fE4mXMtmmbBqTSLY8M0Wc83yRsCpz9eiR4k= type="aes256-gcm96" exportable="true"
# Retrieving transit wrapping key.
# Wrapping source key with ephemeral key.
# Encrypting ephemeral key with transit wrapping key.
# Submitting wrapped key to Vault transit.
# Success!
13) For import_version run the below command with new or existing encryption-key
./byok import_version transit_import/keys/test-key-imp pMmWg4kIpRLBrP+TEVsnCgw4GPIZMWwPpNAZCa7fUY0= type="aes256-gcm96" exportable="true"
# Retrieving transit wrapping key.
# Wrapping source key with ephemeral key.
# Encrypting ephemeral key with transit wrapping key.
# Submitting wrapped key to Vault transit.
# Success!
Importing keys generated using OpenSSL
keys generated with OpenSSL need to be in DER format.
To convert a PEM formatted keyopenssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER -in key.pem -out key.der
After that the key needs to be base64 encoded without line breaks to be used with the import tool.BASE64_KEY=$(base64 -w 0 -i key.der)
./byok import transit_import/keys/test-key $BASE64_KEY type=rsa-2048
(replace with appropriate key type)
For the best security, this sequence is executed as a single command leaving no unencrypted private key files.