Managing Secrets with HashiCorp Vault
Secure storage and management of API keys, credentials, and sensitive data
Managing sensitive information like API keys, database credentials, and certificates is a critical security challenge for modern applications. HashiCorp Vault provides a centralized, secure solution for storing, accessing, and managing secrets with robust access controls, audit logging, and encryption at rest.
This guide demonstrates practical secrets management using Vault’s Key-Value (KV) secrets engine, covering everything from initial setup to production operations.
Prerequisites
- HashiCorp Vault installed and running
- Vault CLI configured and authenticated
- Administrative access to enable secrets engines
- API keys or credentials to store (for testing purposes)
Understanding Vault Secrets Engines
Vault uses secrets engines to handle different types of sensitive data. The Key-Value (KV) engine is the most commonly used for storing static secrets like API keys, passwords, and configuration data.
KV Engine Versions
- KV v1: Simple key-value storage without versioning
- KV v2: Advanced features including versioning, metadata, and soft deletes
Step 1: Verify and Enable Secrets Engine
Check Current Secrets Engines
Before storing secrets, verify which engines are available:
vault secrets list
Expected Output:
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_12345678 per-token private secret storage
identity/ identity identity_87654321 identity store
sys/ system system_abcdef123 system endpoints used for control
Enable KV Secrets Engine
If the KV engine isn’t mounted at the secret/ path, enable it:
# Enable KV v2 (recommended for production)
vault secrets enable -path=secret kv-v2
# Verify successful enablement
vault secrets list
Step 2: Store API Keys and Credentials
Store Individual API Keys
Store your sensitive API keys using organized path structures:
# Store OpenAI API key
vault kv put secret/api-keys/openai \
api_key="sk-proj-your-openai-key-here" \
organization="your-org-id"
# Store Anthropic API key
vault kv put secret/api-keys/anthropic \
api_key="your-anthropic-key-here"
# Store additional service credentials
vault kv put secret/api-keys/github \
token="ghp_your-github-token" \
username="your-github-username"
Store Application Configuration
Group related secrets for easier management:
# Database credentials
vault kv put secret/myapp/database \
username="db_admin" \
password="secure_db_password" \
host="db.example.com" \
port="5432"
# Application settings
vault kv put secret/myapp/config \
app_secret="your-app-secret-key" \
jwt_secret="jwt-signing-key" \
encryption_key="aes-256-key"
Step 3: Retrieve Secrets
View Complete Secrets
Retrieve all key-value pairs for a secret:
# Get full secret with metadata
vault kv get secret/api-keys/openai
# Get secret in JSON format (useful for automation)
vault kv get -format=json secret/api-keys/openai
Sample Output:
====== Secret Path ======
secret/data/api-keys/openai
======= Metadata =======
Key Value
--- -----
created_time 2025-09-25T10:30:00.123456Z
custom_metadata
deletion_time n/a
destroyed false
version 1
========= Data =========
Key Value
--- -----
api_key sk-proj-your-openai-key-here
organization your-org-id
Extract Specific Values
Get individual field values for use in scripts and applications:
# Get only the API key value
vault kv get -field=api_key secret/api-keys/openai
# Get database password
vault kv get -field=password secret/myapp/database
# Store value in environment variable
export OPENAI_API_KEY=$(vault kv get -field=api_key secret/api-keys/openai)
Step 4: Advanced Secrets Management
Version Management (KV v2 Only)
KV v2 maintains version history for all secrets:
# View secret metadata and versions
vault kv metadata get secret/api-keys/openai
# Get specific version
vault kv get -version=1 secret/api-keys/openai
# Update secret (creates new version)
vault kv put secret/api-keys/openai \
api_key="sk-proj-updated-key" \
organization="new-org-id"
Secret Lifecycle Management
Manage secret versions and deletions:
# Soft delete (recoverable)
vault kv delete secret/api-keys/old-service
# Delete specific versions
vault kv delete -versions=1,2 secret/api-keys/openai
# Permanently destroy versions (irreversible)
vault kv destroy -versions=1,2 secret/api-keys/openai
# Undelete soft-deleted secret
vault kv undelete -versions=3 secret/api-keys/old-service
Patch Operations
Update individual fields without affecting others:
# Update only the API key, preserve other fields
vault kv patch secret/api-keys/stripe \
api_key="sk_live_new-stripe-key"
# Add new field to existing secret
vault kv patch secret/myapp/config \
redis_url="redis://cache.example.com:6379"
Step 5: Integration with Applications
Environment Variable Loading
Create scripts to load secrets into environment variables:
#!/bin/bash
# load-secrets.sh
# Load API keys
export OPENAI_API_KEY=$(vault kv get -field=api_key secret/api-keys/openai)
export ANTHROPIC_API_KEY=$(vault kv get -field=api_key secret/api-keys/anthropic)
# Load database credentials
export DB_USERNAME=$(vault kv get -field=username secret/myapp/database)
export DB_PASSWORD=$(vault kv get -field=password secret/myapp/database)
export DB_HOST=$(vault kv get -field=host secret/myapp/database)
# Start application with loaded secrets
./start-application.sh
Application Integration Examples
Python Application:
import subprocess
import os
def get_vault_secret(path, field):
"""Retrieve secret from Vault"""
result = subprocess.run([
'vault', 'kv', 'get', '-field=' + field, path
], capture_output=True, text=True)
if result.returncode == 0:
return result.stdout.strip()
else:
raise Exception(f"Failed to retrieve secret: {result.stderr}")
# Usage
openai_key = get_vault_secret('secret/api-keys/openai', 'api_key')
db_password = get_vault_secret('secret/myapp/database', 'password')
Troubleshooting Common Issues
Permission Denied (403) Error
Symptoms:
Error making API request.
Code: 403. Errors: * preflight capability check returned 403
Solution:
# Enable KV v2 at secret/ path
vault secrets enable -path=secret kv-v2
No Handler for Route Error
Symptoms:
Error: no handler for route 'secret/mykey'
Solution:
# Verify secrets engine is mounted
vault secrets list
Secret Not Found
Symptoms:
No value found at secret/data/mykey
Solution:
# List available secrets
vault kv list secret/
Security Best Practices
Path Organization
Recommended Structure:
secret/
├── api-keys/
│ ├── openai
│ ├── anthropic
│ └── github
├── databases/
│ ├── production
│ └── staging
└── applications/
├── webapp/config
└── api/credentials
Conclusion
HashiCorp Vault provides enterprise-grade secrets management with the flexibility to accommodate various use cases and security requirements. By implementing proper secret storage, retrieval, and lifecycle management practices, organizations can significantly improve their security posture while maintaining operational efficiency.
Key Benefits: Centralized secret management, version control, access policies, and seamless application integration make Vault an essential tool for modern security architectures.
