Static secrets: Key/value secrets engine
Vault can be used to store any secret in a secure manner. The secrets may be SSL certificates and keys for your organization's domain, credentials to connect to a corporate database server, etc. Storing such sensitive information in plaintext is not desirable.
Note
This tutorial demonstrates the use of Key/Value Secrets Engine Version 1. To learn about Key/Value Secrets Engine Version 2, refer to the Versioned Key/Value Secrets Engine tutorial.
Personas
The end-to-end scenario described in this tutorial involves two personas:
Challenge
Consider the following situations:
- Developers use a single admin account to access a third-party app (e.g. Splunk) and anyone who knows the user ID and password can log in as an admin
- SSH keys to connect to remote machines are shared and stored as a plaintext
- API keys to invoke external system APIs are stored as a plaintext
- An app integrates with LDAP, and its configuration information is in a plaintext
Organizations often seek an uniform workflow to securely store this sensitive information.
Solution
Use Vault as centralized secret storage to secure any sensitive information. Vault encrypts these secrets using 256-bit AES in GCM mode with a randomly generated nonce prior to writing them to its persistent storage. The storage backend never sees the unencrypted value, so even if an attacker gained access to the raw storage, they wouldn't be able to read your secrets.
Launch Terminal
This tutorial includes a free interactive command-line lab that lets you follow along on actual cloud infrastructure.
Prerequisites
To perform the tasks described in this tutorial, you need to have:
Vault binary installed. Refer to the Getting Started tutorial.
jq to format the JSON output to follow the Vault API steps.
Policy requirements
Note
For the purpose of this tutorial, you can use the root
token to
work with Vault. However, it is recommended that root tokens are only used for
just enough initial setup or in emergencies. As a best practice, use tokens with
appropriate set of policies based on your role in the organization.
To perform all tasks demonstrated in this tutorial, your policy must include the following permissions:
If you are not familiar with policies, complete the policies tutorial.
Scenario Introduction
This tutorial demonstrates the basic steps to store secrets using Vault. The scenario here is to store the following secrets:
- API key (Google API)
- Root certificate of a production database (MySQL)
To store your API key within the configured physical storage for Vault, use the key/value secrets engine.
The Key/Value secrets engine passes any operation through to the configured storage backend for Vault. For example, if your Vault server is configured with Consul as its storage backend, a "read" operation turns into a read from Consul at the same path.
You will perform the following:
- Start Vault
- Enable KV Secrets Engine
- Store the Google API key
- Store the root certificate for MySQL
- Generate a token for apps
- Retrieve the secrets

Lab Setup
In another terminal, start a Vault dev server with
root
as the root token.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.
The Vault server is ready.
Enable KV Secrets Engine
Currently, when you start the Vault server in dev
mode, it
automatically enables v2
of the KV secrets engine at secret/
.
This tutorial focuses on key/value v1 secrets engine. The Versioned Key/Value Secret Engine tutorial highlights features that are specific to the key/value v2 secrets engine.
Enable the key/value secrets engine v1 at
kv-v1/
.List enabled secrets engines.
You should see
kv-v1/
listed.
Store the Google API key
Everything after the kv-v1
path is a key-value pair to write to the
secrets engine. You can specify multiple values. If the value has a space, you
need to surround it with quotes. Having keys with spaces is permitted, but
strongly discouraged because it can lead to unexpected client-side behavior.
Let's assume that the path convention in your organization is
kv-v1/<OWNER>/apikey/<APP>
for API keys. To store the Google API key used
by the engineering team, the path would be kv-v1/eng/apikey/Google
. If you
have an API key for New Relic owned by the DevOps team, the path would look like
kv-v1/devops/apikey/New_Relic
.
To set key/value secrets:
The <PATH>
can be anything you want it to be, and your organization should
decide on the naming convention that makes most sense.
Create a secret at path
kv-v1/eng/apikey/Google
with akey
set toAAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI
.Read back the secret at path
kv-v1/eng/apikey/Google
Store the root certificate for MySQL
For the purpose of this tutorial, generate a mock certificate using OpenSSL.
The generated cert.pem
displays something similar to the following.
Note
If you don't have OpenSSL, copy the above certificate and
save it as cert.pem
.
The command is basically the same as the Google API key example. The path
convention for certificates is kv-v1/<ENVIRONMENT>/cert/<SYSTEM>
. To
store the root certificate for production MySQL, the path becomes
kv-v1/prod/cert/mysql
.
Create a secret at path kv-v1/prod/cert/mysql
with a cert
set to file
contents for cert.pem
.
Note
Any value that begins with @
indicates a file name. Data will be
loaded from this file.
Generate a token for apps
To read the secrets, apps
persona needs "read" ability on those secrets engine
paths.
Create a policy file named apps-policy.hcl
that permits the read
to the
paths kv-v1/eng/apikey/Google
and kv-v1/prod/cert/mysql
.
First create
apps
policyCreate a variable that stores a new token with
apps
policy attached.Display the token.
Now
apps
can use this token to read the secrets.
Note
For the purposes of this tutorial, you created a policy for the
apps
persona, and generated a token for it. However, in the real world, you
may have a dedicated policy author
, or admin
to write policies. Also, the
consumer of the API key may be different from the consumer of the root
certificate. Then each persona would have a policy based on what it needs to
access.

Retrieve the secrets
Using the token from the Generate a token for apps step, read the Google API key and the root certificate for MySQL.
The command to read a secret is:
Read the secret at the path
kv-v1/eng/apikey/Google
using the apps token.Read only the
key
field at the pathkv-v1/eng/apikey/Google
.Read only the
cert
field at the pathkv-v1/prod/cert/mysql
.The result displays the certificate.
Additional discussion
Q: How do I enter my secrets without exposing the secret in my shell's history?
As a precaution, you may wish to avoid passing your secret as a part of the CLI command so that the secret won't appear in the history file. Here are a few techniques you can use.
Option 1: Use a dash "-"
An easy technique is to use a dash "-" and then press Enter. This allows you to
enter the secret on a new line. After entering the secret, press Ctrl+d
to
end the pipe which will write the secret to the Vault.
Option 2: Read the secret from a file
The key-value pairs for a secret may be defined in a file.
Create a file named apikey.json
that defines the key
field.
Create a secret at path kv-v1/eng/apikey/Google
with keys and values defined
in apikey.json
.
Option 3: Disable all vault command history
The first two options ensure that the contents of the secret do not appear in the shell history. The secret path would still be accessible through the shell history.
You can configure your shell to avoid logging any vault
commands to your
history.
In bash
, set the history to ignore all commands that start with vault
.
Note
This prevents vault
commands from appearing when using the Up
arrow or when searching command history with <Ctrl-r>
.
Q: How do I save multiple values at once?
The tutorial examples demonstrating a secret with a single key-value pair. Multiple key-value pairs may be provided in a single command.
Create a secret at path kv-v1/dev/config/mongodb
that sets the url
,
db_name
, username
, and password
.
Multiple key-value pairs may be defined in a file provided to the command.
Create a file named mongodb.json
that defines the url
, db_name
, username
,
and password
fields.
Create a secret at path kv-v1/dev/config/mongodb
with keys and values defined
in mongodb.json
.
Q: How do I store secrets generated by Vault in KV secrets engine?
Assuming that you have AppRole auth method enabled (refer to the AppRole Pull Authentication tutorial).
The following command retrieves the Secret ID of the jenkins
role, encode it
with base64, and stores the value in the kv-v1/secret-id
path.
Output:
Clean up
If you wish to clean up your environment after completing the tutorial, follow the steps in this section.
Unset the
VAULT_TOKEN
environment variable.Unset the
VAULT_ADDR
environment variable.HCP Vault users: Unset the
VAULT_NAMESPACE
environment variable.If you are running Vault locally in
dev
mode, stop the Vault dev server by pressing Ctrl+C where the server is running. Or, execute the following command.Delete created files.
Help and Reference
- Key/Value Secrets Engine
- Key/Value Secrets Engine API
- Client libraries for Vault APIfor commonly used languages