Last updated: 2026-02-11
HashiCorp Vault TLS/SSL Configuration Guide
This guide provides recommended TLS/SSL settings for HashiCorp Vault, a secrets management tool. Vault stores and controls access to sensitive data such as API keys, passwords, and certificates. TLS is critical for Vault because all secrets transit the network through its API.
Prerequisites
- HashiCorp Vault 1.12 or later
- A valid SSL/TLS certificate
- Vault is built with Go's
crypto/tls, which provides strong TLS defaults
Certificate Setup
Vault needs a certificate that includes all hostnames and IP addresses clients will use to connect:
chmod 640 /etc/vault/ssl/privkey.pem
chown vault:vault /etc/vault/ssl/privkey.pem
chmod 644 /etc/vault/ssl/fullchain.pem
Listener Configuration
Vault's TLS settings are configured in the listener stanza of the Vault configuration file (/etc/vault.d/vault.hcl).
Basic TLS Setup
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/ssl/fullchain.pem"
tls_key_file = "/etc/vault/ssl/privkey.pem"
}
Setting
tls_disable = truedisables TLS entirely. Never do this in production. Vault will refuse to start in production mode without TLS unless explicitly disabled, and all secrets would transit the network in plaintext.
Minimum TLS Version
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/ssl/fullchain.pem"
tls_key_file = "/etc/vault/ssl/privkey.pem"
tls_min_version = "tls12"
}
Available values: tls10, tls11, tls12, tls13.
Cipher Suites
Vault uses Go's cipher suite names. Configure allowed cipher suites for TLS 1.2 (TLS 1.3 ciphers are not configurable in Go and are always secure):
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/ssl/fullchain.pem"
tls_key_file = "/etc/vault/ssl/privkey.pem"
tls_min_version = "tls12"
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
}
Client Certificate Authentication
To require clients to present a TLS certificate (mutual TLS):
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/ssl/fullchain.pem"
tls_key_file = "/etc/vault/ssl/privkey.pem"
tls_min_version = "tls12"
tls_client_ca_file = "/etc/vault/ssl/ca.pem"
tls_require_and_verify_client_cert = true
}
Disable Client Cache Headers
For additional security, disable client-side caching of Vault responses:
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/ssl/fullchain.pem"
tls_key_file = "/etc/vault/ssl/privkey.pem"
tls_min_version = "tls12"
tls_disable_client_certs = false
custom_response_headers {
"default" = {
"Strict-Transport-Security" = ["max-age=63072000; includeSubDomains; preload"]
}
}
}
Cluster TLS
In high-availability (HA) deployments, Vault nodes communicate with each other through the cluster port. Configure TLS for cluster communication:
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_cert_file = "/etc/vault/ssl/fullchain.pem"
tls_key_file = "/etc/vault/ssl/privkey.pem"
tls_min_version = "tls12"
}
Vault automatically uses TLS for cluster communication when the listener has TLS enabled. For separate cluster certificates:
cluster_addr = "https://vault-node1.example.com:8201"
Complete Configuration
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_cert_file = "/etc/vault/ssl/fullchain.pem"
tls_key_file = "/etc/vault/ssl/privkey.pem"
tls_min_version = "tls12"
tls_cipher_suites = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
custom_response_headers {
"default" = {
"Strict-Transport-Security" = ["max-age=63072000; includeSubDomains; preload"]
}
}
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault-node1.example.com:8201"
ui = true
Vault as a CA (PKI Secrets Engine)
Vault can also act as a certificate authority using the PKI secrets engine. This is useful for issuing TLS certificates to other services:
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
vault write pki/root/generate/internal \
common_name="Internal CA" \
ttl=87600h
vault write pki/config/urls \
issuing_certificates="https://vault.example.com:8200/v1/pki/ca" \
crl_distribution_points="https://vault.example.com:8200/v1/pki/crl"
Client Configuration
Environment Variables
export VAULT_ADDR="https://vault.example.com:8200"
export VAULT_CACERT="/path/to/ca.pem"
For mutual TLS:
export VAULT_CLIENT_CERT="/path/to/client-cert.pem"
export VAULT_CLIENT_KEY="/path/to/client-key.pem"
CLI Usage
vault status -ca-cert=/path/to/ca.pem -address=https://vault.example.com:8200
Skip Verification (Development Only)
export VAULT_SKIP_VERIFY=true
Never use
VAULT_SKIP_VERIFYin production. This disables all certificate verification.
Verification
Start or restart Vault:
systemctl restart vault
Check Vault's status:
vault status
Test the TLS connection:
openssl s_client -connect vault.example.com:8200
Verify the certificate details:
curl --cacert /path/to/ca.pem https://vault.example.com:8200/v1/sys/health