What it is
HashiCorp Vault is a tool for securely accessing secrets, controlling access to them, and encrypting/decrypting data. You reach for it when you need to manage sensitive information like API keys, passwords, certificates, and encryption keys in a centralized, auditable, and secure way.
Installation
Linux (using apt for Debian/Ubuntu):
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vault
Linux (using yum for RHEL/CentOS/Fedora):
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo yum -y install vault
macOS (using Homebrew):
brew install hashicorp/tap/vault
Windows (using Chocolatey):
choco install vault
Download Binary: Visit the official Vault releases page on GitHub and download the appropriate binary for your operating system and architecture. Extract the binary and place it in your system’s PATH.
Core Concepts
- Vault Server: The core process that stores secrets, manages authentication, and enforces authorization policies.
- Client: Any entity (user, application, service) that interacts with the Vault server to read, write, or manage secrets.
- Secrets: Sensitive data stored in Vault, such as passwords, API keys, certificates, or tokens.
- Auth Methods: Mechanisms by which clients authenticate to Vault. Examples include Token, AppRole, Kubernetes, AWS IAM, LDAP, etc.
- Secrets Engines: Components that store, generate, or encrypt/decrypt data. Examples include Key/Value (KV), database, PKI, Transit, etc.
- Policies: Rules that define what authenticated clients are allowed to do within Vault.
- Lease: Most secrets in Vault have a Time-To-Live (TTL). When the TTL expires, the secret is considered "revoked" and can be cleaned up.
- Seal/Unseal: Vault is initialized in a "sealed" state, meaning it cannot decrypt its storage. It must be "unsealed" by providing a certain number of unseal keys. Once unsealed, it remains unsealed until explicitly sealed again or restarted.
- Namespaces (Enterprise Feature): A way to isolate Vault resources for different teams or applications within a single Vault cluster.
Commands / Usage
Server Management
Start a development server (in-memory, not for production):
vault server -dev
This command starts a single-node Vault server with a default root token and a development KV secrets engine. It’s useful for local testing.
Start a server in server mode (requires configuration):
vault server -config=/path/to/vault.hcl
Starts a Vault server using the specified configuration file. The configuration file defines storage backends, listener addresses, TLS settings, etc.
Initialize a new Vault cluster:
vault operator init
This command generates the initial unseal keys and a root token. You’ll need to securely store these. The output will look something like:
Unseal Key 1: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Unseal Key 2: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
...
Initial Root Token: s.xxxxxxxxxxxxxxxxxxxx
Unseal a sealed Vault server:
vault operator unseal <unseal_key>
Repeat this command with N unseal keys, where N is the threshold configured during initialization (e.g., 3 out of 5 keys).
Check Vault status:
vault status
Shows if Vault is initialized, sealed, and the progress of unsealing.
Seal a Vault server:
vault operator seal
This command will seal the Vault server, requiring it to be unsealed again before any operations can be performed.
Perform a Vault audit device enable:
vault audit enable <type> [options]
Enables an audit device to log all requests and responses.
Example: vault audit enable file file_path=/var/log/vault/audit.log
Perform a Vault audit device disable:
vault audit disable <name>
Disables an audit device.
Authentication and Authorization
Login using a token:
vault login -token=<your_token>
Authenticates to Vault using a static token.
Login using AppRole:
vault write auth/approle/login role_id=<role_id> secret_id=<secret_id>
Authenticates to Vault using the AppRole authentication method.
Login using Kubernetes:
vault write auth/kubernetes/login role=<k8s_role_name> jwt=<service_account_jwt>
Authenticates to Vault using the Kubernetes authentication method.
List all enabled authentication methods:
vault auth list
Shows all the authentication methods that are currently enabled in Vault.
Enable an authentication method:
vault auth enable <type>
Enables a new authentication method.
Example: vault auth enable approle
Disable an authentication method:
vault auth disable <type>
Disables an authentication method.
List all policies:
vault policy list
Shows all the policies currently defined in Vault.
Read a policy:
vault policy read <policy_name>
Displays the rules for a specific policy.
Example: vault policy read default
Write/Create a policy:
vault policy write <policy_name> <policy_file.hcl>
Creates or updates a policy from an HCL file.
Example: vault policy write web-app web-app-policy.hcl
Delete a policy:
vault policy delete <policy_name>
Removes a policy.
List all entities:
vault entity list
Lists all entities managed by Vault.
Read an entity:
vault entity read <entity_id>
Displays information about a specific entity.
Create an entity:
vault entity create name=<entity_name> policies=<policy1>,<policy2>
Creates a new entity.
Update an entity:
vault entity upsert <entity_id> name=<new_name> policies=<policy1>,<policy2>
Updates an existing entity.
Delete an entity:
vault entity delete <entity_id>
Deletes an entity.
List all tokens:
vault token list
Lists all tokens currently in Vault.
Read token information:
vault token lookup <token_id>
Retrieves metadata about a specific token.
Create a token:
vault token create -policy=<policy_name> -ttl=<duration>
Creates a new token with specified policies and TTL.
Example: vault token create -policy=web-app -ttl=24h
Renew a token:
vault token renew -increment=<duration> <token_id>
Renews a token, extending its lease.
Example: vault token renew -increment=1h abcdef12-3456-7890-abcd-ef1234567890
Revoke a token:
vault token revoke <token_id>
Revokes a token, making it invalid.
Revoke a token and all its children:
vault token revoke -recursive <token_id>
Revokes a token and all tokens created from it.
Secrets Management (KV Secrets Engine)
Enable the KV secrets engine:
vault secrets enable kv
Enables the KV v2 secrets engine at the default path secret/.
To enable at a custom path: vault secrets enable -path=my-kv kv
Write a secret:
vault kv put secret/<path> key1=value1 key2=value2
Writes or updates a secret at a given path.
Example: vault kv put secret/myapp/config api_key=abc123db9876 database_password=S3cr3tP@ssw0rd
Read a secret:
vault kv get secret/<path>
Reads a secret from a given path.
Example: vault kv get secret/myapp/config
List secrets at a path:
vault kv list secret/<path>
Lists the keys of secrets at a given path.
Example: vault kv list secret/myapp/
Delete a secret:
vault kv delete secret/<path>
Deletes a secret at a given path.
Example: vault kv delete secret/myapp/config
Destroy a secret (KV v2):
vault kv destroy secret/<path>
Marks a secret for deletion. In KV v2, this moves it to a soft-delete state before permanent deletion.
Undelete a secret (KV v2):
vault kv undelete secret/<path> <version_number>
Restores a previously destroyed secret version. You need to know the version number.
Secrets Management (Database Secrets Engine)
Enable the database secrets engine:
vault secrets enable database
Enables the database secrets engine at the default path database/.
Configure a database connection:
vault write database/config/<name> \
plugin_name=<plugin_name> \
{% raw %}
connection_url="{{username}:${password}@tcp(127.0.0.1:3306)/?tls=false" \
{% endraw %}
username="vault_user" \
password="vault_password"
Configures Vault to connect to a database. Replace placeholders with actual database details.
Example: vault write database/config/mysql plugin_name=mysql-database-plugin connection_url="root:my-secret-pw@tcp(127.0.0.1:3306)/?tls=false" username="root" password="my-secret-pw"
Create a database role:
vault write database/roles/<role_name> \
db_name=<database_config_name> \
{% raw %}
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON inventory.* TO '{{name}}'@'%';" \
{% endraw %}
default_ttl="1h" \
max_ttl="24h"
Defines a role that specifies how to create and grant permissions to new database users.
{% raw %}
Example: vault write database/roles/readonly db_name=mysql creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON inventory.* TO '{{name}}'@'%';" default_ttl="30m" max_ttl="1h"
{% endraw %}
Generate dynamic database credentials:
vault read database/creds/<role_name>
Requests a set of dynamic database credentials for a given role.
Example: vault read database/creds/readonly
Secrets Management (PKI Secrets Engine)
Enable the PKI secrets engine:
vault secrets enable pki
Enables the PKI secrets engine at the default path pki/.
Configure PKI backend:
vault write pki/config \
max_lease_ttl="8760h" \
default_lease_ttl="720h" \
allow_localhost="true"
Configures the PKI backend’s lease times and other settings.
Generate a root CA certificate:
vault write pki/root/generate/internal \
common_name="My Root CA" \
ttl="87600h"
Generates a self-signed root CA certificate.
Create a certificate authority (CA):
vault write pki/intermediate/generate/internal \
common_name="My Intermediate CA" \
ttl="8760h"
Generates an intermediate CA certificate signed by the root CA.
Configure a certificate role:
allow_any_name="true" \
max_ttl="72h" \
key_type="rsa" \
key_bits="2048" \
allow_bare_domains="true" \
allowed_domains="example.com,internal.example.com" \
allow_subdomains="true"
Defines a role that specifies the parameters for issuing certificates.
Example: vault write pki/roles/webserver allow_any_name="true" max_ttl="24h" key_type="rsa" key_bits="2048" allowed_domains="example.com" allow_subdomains="true"
Issue a certificate:
vault read pki/issue/<role_name> common_name="server.example.com" ttl="1h"
Requests a certificate for a specific common name and TTL.
Example: vault read pki/issue/webserver common_name="web.example.com" ttl="1h"
Secrets Management (Transit Secrets Engine)
Enable the Transit secrets engine:
vault secrets enable transit
Enables the Transit secrets engine at the default path transit/.
Create an encryption key:
vault write transit/keys/<key_name> type=aes256-gcm
Creates a named encryption key.
Example: vault write transit/keys/my-app-key type=aes256-gcm
Encrypt data:
vault write transit/encrypt/<key_name> plaintext=<base64_encoded_data>
Encrypts data using the specified key. The plaintext must be base64 encoded.
Example: echo -n "my-secret-data" | base64 | vault write transit/encrypt/my-app-key plaintext=$(cat)
Decrypt data:
vault write transit/decrypt/<key_name> ciphertext=<base64_encoded_ciphertext>
Decrypts data using the specified key. The ciphertext must be base64 encoded.
Example: vault write transit/decrypt/my-app-key ciphertext=gAAAAAB...
Sign data:
vault write transit/sign/<key_name> input=<base64_encoded_data> signature_algorithm=pkcs1-sha2-256
Signs data using the specified key.
Example: echo -n "data-to-sign" | base64 | vault write transit/sign/my-signing-key input=$(cat) signature_algorithm=pkcs1-sha2-256
Verify signature:
vault write transit/verify/<key_name> input=<base64_encoded_data> signature=<base64_encoded_signature> signature_algorithm=pkcs1-sha2-256
Verifies a signature against the data using the specified key.
Other Operations
List enabled secrets engines:
vault secrets list
Shows all the secrets engines mounted in Vault.
Mount a secrets engine:
vault secrets enable <type> -path=<mount_path>
Mounts a new secrets engine at a specified path.
Example: vault secrets enable kv -path=secrets/dev
Unmount a secrets engine:
vault secrets disable <mount_path>
Unmounts a secrets engine.
Example: vault secrets disable secret/
List ACL policies:
vault token capabilities <token_id> <path>
Checks the capabilities of a token against a given path.
Example: vault token capabilities abcdef12-3456-7890-abcd-ef1234567890 secret/myapp/config
Enable a secrets engine:
vault secrets enable <type>
Enables a secrets engine.
Example: vault secrets enable pki
Common Patterns
Reading a secret into an environment variable:
export MY_API_KEY=$(vault kv get -field=api_key secret/myapp/config | grep -A 1 "api_key" | tail -n 1 | awk '{print $2}')
echo "API Key loaded: $MY_API_KEY"
This pattern is common for injecting secrets into application environments.
Using Vault with curl (for API calls):
VAULT_ADDR="http://127.0.0.1:8200"
VAULT_TOKEN="s.xxxxxxxxxxxxxxxxxxxx" # Replace with your token
curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request GET \
$VAULT_ADDR/v1/secret/myapp/config
Directly interacting with the Vault API.
Using Vault Agent to manage secrets for applications: Vault Agent can be configured to automatically authenticate, retrieve secrets, and render them into files or environment variables for applications. This is a more advanced but robust pattern for application integration.
Dynamic database credential rotation:
# Application requests credentials
DB_CREDS=$(vault read -field=username database/creds/readonly)
DB_PASS=$(vault read -field=password database/creds/readonly)
# Application uses DB_CREDS and DB_PASS
# After the TTL expires, Vault automatically revokes the credentials.
Encrypting/Decrypting data on the fly:
# Encrypt
echo -n "sensitive info" | base64 | vault write transit/encrypt/my-key plaintext=$(cat) -field=ciphertext | tee encrypted.b64
# Decrypt
vault read transit/decrypt/my-key ciphertext=$(cat encrypted.b64) -field=plaintext | base64 -d
Gotchas
- Development Server is In-Memory: Secrets stored using
vault server -devare lost when the server stops. It’s only for local testing and development. - Root Token Security: The initial root token generated during
vault operator initis extremely powerful. Secure it like a master key. It’s recommended to use it only once to set up initial authentication methods and policies, then revoke it. - Unseal Keys Management: The unseal keys are critical for accessing your Vault data. If you lose enough unseal keys (less than the threshold), your data becomes irrecoverable. Distribute them securely among trusted individuals or systems.
- Lease Management: Most secrets have a TTL. If an application needs a secret for longer than its lease, it must renew the lease before it expires. Otherwise, the secret will be revoked.
- KV v1 vs KV v2: KV v2 has versioning, soft deletes, and undelete capabilities, making it more robust. KV v1 is simpler but lacks these features. Use KV v2 unless you have a specific reason not to.
- Token vs. AppRole Authentication: Static tokens are easy to use but harder to manage and revoke at scale. AppRole is designed for machine-to-machine authentication and is generally preferred for applications and services.
- TLS Configuration: For production, always run Vault with TLS enabled to encrypt communication. This requires configuring listeners and potentially a backend for certificate management.
- Storage Backend Choice: The choice of storage backend (e.g., Consul, integrated storage, file) impacts performance, resilience, and HA capabilities. Integrated storage is generally recommended for new deployments.