Auto-unseal Vault using transit secrets engine
When a Vault server is started, it starts in a sealed state and it does not know how to decrypt data. Before any operation can be performed on the Vault, it must be unsealed. Unsealing is the process of constructing the master key necessary to decrypt the data encryption key.
Challenge
Vault unseal operation requires a quorum of existing unseal keys split by Shamir's Secret sharing algorithm. This is done so that the "keys to the kingdom" won't fall into one person's hand.
However, this process is manual and can become painful when you have many Vault clusters as there are now many different key holders with many different keys.
Solution
Vault supports opt-in automatic unsealing via transit secrets engine. This feature enables operators to delegate the unsealing process to a trusted Vault environment to ease operations.
This tutorial demonstrates how to auto-unseal a Vault with Transit secrets engine.
To auto-unseal your Vault with cloud provider's key, refer to the following tutorials:
Prerequisites
To perform the tasks described in this tutorial, you need Vault 1.1 or later.
Scenario introduction
For the purpose of demonstration, you are going to run two instances of Vault as described in the following diagram:
In reality, the Vault 1 and Vault 2 are two separate stand-alone Vault clusters where one protecting another's root key. Nonetheless, the steps described in this tutorial directly applies to your clustered environment. The main difference would be the location (address) of Vault 1 and Vault 2.
In this scenario, Vault 1 ($VAULT_ADDR
) is the encryption
service provider, and its transit key protects the Vault 2 server's master
key.
Step 1: Configure auto-unseal key provider (Vault 1)
If you prefer running a script instead of manually setting up the Vault 1 server, follow the steps below.
Create a setup script namde
autounseal-transit-setup.sh
.autounseal-transit-setup.shMake the file executable.
Run the script.
Output:
Now, you can skip to Step 2: Configure auto-unseal (Vault 2) section.
Start Vault 1 server
Start a Vault dev server with
root
as the root token. Output the system log in a file namedvault-1.log
.The Vault dev server defaults to running at
127.0.0.1:8200
. The server is also initialized and unsealed.Insecure operation
Do not run a Vault dev server in production. This approach is only used here to simplify the unsealing process for this demonstration.
Export an environment variable for the
vault
CLI to address the Vault server.Export an environment variable for the
vault
CLI to authenticate with the Vault server.
Setup the transit secrets engine
The first step is to enable and configure the transit
secrets engine on
Vault 1.
Enable an audit device if it hasn't been enabled already so that you can examine the audit log later in Step 3.
Execute the following command to enable the
transit
secrets engine.Execute the following command to create an encryption key named, "autounseal".
Note
To learn more about the
transit
secrets engine, refer to the Encryption as a Service: Transit Secrets Engine.Create a policy named
autounseal
which permitsupdate
againsttransit/encrypt/autounseal
andtransit/decrypt/autounseal
paths.Output:
Create an orphan periodic client token with the
autounseal
policy attached and response wrap it with TTL of 120 seconds. Store the generated wrapping token value in a file,wrapping-token.txt
.Note
Periodic tokens can be renewed within the
period
. By default, the transitautounseal
token is renewed automatically. Anorphan
token does not have a parent token and will not be revoked when the token that created it expires. Learn more about token hierarchies.The generated
wrapping_token
is what you pass to Vault 2 so that its root key can be decrypted to unseal.Example output:
Step 2: Configure auto-unseal (Vault 2)
Now, start a second Vault instance which listens to port 8100. The server
configuration file should define a seal
stanza with parameters properly set
based on the tasks you performed in Step 1.
Execute the following command to unwrap the secrets passed from Vault 1 and retrieve the token value.
Example output:
Open a terminal where you will run the Vault 2 server, and set
VAULT_TOKEN
environment variable whose value is the client token you just unwrapped.Example:
Create a server configuration file (
config-autounseal.hcl
) to start a second Vault instance (Vault 2).Notice that the
address
points to the Vault server listening to port 8200 (Vault 1). Thekey_name
andmount_path
match to what you created in Step 1.Note
The
seal
stanza does not set thetoken
value since it's already set asVAULT_TOKEN
environment variable.Warning
Although the listener stanza disables TLS (
tls_disable = "true"
) for this tutorial, Vault should always be used with TLS in production to provide secure communication between clients and the Vault server. It requires a certificate file and key file on each Vault host.Create the raft path directory as configured in the storage stanza.
Start the server using the configuration.
Open another terminal and initialize your second Vault server (Vault 2).
By passing the
VAULT_ADDR
, the subsequent command gets executed against the second Vault server (http://127.0.0.1:8100).Example output:
Note
The initialization generates recovery keys (instead of unseal keys) when using auto-unseal. Some of the Vault operations still require Shamir keys. For example, to regenerate a root token, each key holder must enter their recovery key. Similar to unseal keys, you can specify the number of recovery keys and the threshold using the
-recovery-shares
and-recovery-threshold
flags. It is strongly recommended to initialize Vault with PGP.Check the Vault 2 server status. It is now successfully initialized and unsealed.
Notice that it shows
Total Recovery Shares
instead ofTotal Shares
. The transit secrets engine is solely responsible for protecting the root key of Vault 2.
Step 3: Verify auto-unseal
When you stop and start the Vault 2 server, it comes up in the
unsealed
state and ready for operations.
To verify that Vault 2 gets automatically unseal, press Ctrl + C to stop the Vault 2 server where it is running.
Note that Vault 2 is now sealed.
When you try to check the Vault status, it returns the "connection refused" message.
Press the upper-arrow key, and execute the
vault server -config=config-autounseal.hcl
command again to start Vault 2 and see what happens.Notice that the Vault server is already unsealed. The Transit Address is set to your Vault 1 which is listening to port 8200 (
$VAULT_ADDR
).Check the Vault 2 server status.
Vault 2 is automatically unsealed.
Now, examine the audit log in Vault 1.
You should see an
update
request against thetransit/decrypt/autounseal
path. Theremote_address
is127.0.0.1
in this example since Vault 1 and Vault 2 are both running locally. If the Vault 2 is running on a different host, the audit log will show the IP address of the Vault 2 host.
Warning
If a security incident forces you to seal the Vault server using the vault operator seal
command, it requires the threshold number of recovery keys to
unseal Vault and bring it back to operation.
Clean up
Execute the following command to stop the Vault servers.
Unset the
VAULT_TOKEN
andVAULT_ADDR
environment variables.Delete the generated files.
Delete the raft directory.