Skip to main content

KV Static Secrets Simple

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.

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:

  1. Start Vault
  2. Enable KV Secrets Engine
  3. Store the Google API key
  4. Store the root certificate for MySQL
  5. Generate a token for apps
  6. Retrieve the secrets

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.

List enabled secrets engines.

vault secrets list -detailed

Under the Options, the version number is indicated.

Enable the key/value secrets engine v1 at kv-v1/.

vault secrets enable -path="kv-v1" kv

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/ 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:

vault kv put kv-v1/<PATH> <KEY>=VALUE>

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 a key set to AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI.

vault kv put kv-v1/eng/apikey/Google key=AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVx

Read back the secret at path kv-v1/eng/apikey/Google

vault kv get kv-v1/eng/apikey/Google

Store the root certificate for MySQL

For the purpose of this tutorial, generate a mock certificate using OpenSSL.

openssl req -x509 -sha256 -nodes -newkey rsa:2048 -keyout selfsigned.key -out cert.pem

The generated cert.pem displays something similar to the following.

-----BEGIN CERTIFICATE-----
MIICyjCCAbICCQDrpZYh8et7yTANBgkqhkiG9w0BAQsFADAnMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExCzAJBgNVBAcMAlNGMB4XDTE4MTExMjIwNDEwNVoXDTE4
MTIxMjIwNDEwNVowJzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQswCQYDVQQH
DAJTRjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnIdgpml8+xk+Oj
1RGMCyJ1P15RiM6rdtszT+DFBg893Lqsjoyd5YgwELLz0Ux8nviG4L5OXOujEpAP
2cQBxTSLQjBELBZY9q0Qky3+2ewqV6lSfcXrcf/JuDJGR5K8HSqwNG35R3WGnZ+O
JhY0Dmx06IAs/FF8gP88zTQ8M7zuaThkF8MaF4sWPf6+texQwjzk4rewknGBFzar
9wFxVwNCyDD6ewIYPtgDxdJ1bwBVoX3KKKXm8GStl/Zva0aEtbSq/161J4VbTro2
dxArMPKzxjD6NLyF59UNs7vbzyfiw/Wq7BJzU7Kued5KdGt0bEiyWZYO+EvvxGmE
1pHfqysCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAavj4CA+7XFVHbwYMbK3c9tN/
73hkMvkAZWix5bfmOo0cNRuCeJnRIX+o6DmusIc8eXJJJV/20+zoSvUwlsLDPXoN
+c41GfIiEUSaSdSBtETMy8oPga718nIwAvNgYiUHXnV3B0nLYBUpYSnsD00/6VXG
xZUIEVBd7Ib5aRwmK8U5drxoWaBoG5qdvH9iapwTrCcPsRjsLBq7Iza2oBORGlfF
CjqiW2+KJzwRiTQj70yceniGVHM+VSpFYCLJ0mXeyLfITy7joqxr4AGYz+EhpLuf
iDpYDNYlr0JDVQqogskWjrnWOh0YcIJKgVtiTh2HDM5TdQgeXg4wv5IqLok0Tw==
-----END CERTIFICATE-----

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/. 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.

vault kv put kv-v1/prod/cert/mysql [email protected]

NOTE: Any value that begins with @ indicates a file name. Data will be loaded from this file.