Loading content...
In the landscape of secrets management, HashiCorp Vault stands as the de facto standard for organizations that demand enterprise-grade security, extensive flexibility, and integration with virtually any infrastructure. Vault isn't merely a secrets storage system—it's a comprehensive secrets lifecycle management platform that fundamentally transforms how organizations handle sensitive data.
Vault emerged from HashiCorp's deep expertise in infrastructure automation, filling a critical gap: how do you manage secrets in dynamic, cloud-native environments where traditional approaches fail? The answer is a system that treats secrets as first-class citizens with their own lifecycle, access controls, and audit capabilities.
By the end of this page, you will understand Vault's architecture, core concepts, and operational patterns. You'll be equipped to design Vault deployments for production environments, understand dynamic secret generation, and implement robust access control policies that scale with your organization.
Before diving into Vault's mechanics, it's essential to understand the problems it solves. Traditional secrets management approaches often involve:
These approaches create fundamental security risks: secrets sprawl, lack of auditability, impossible-to-track access patterns, and credentials that persist indefinitely even after team members leave or systems are decommissioned.
Vault's fundamental insight is that secrets should be treated like infrastructure: managed declaratively, versioned, audited, and automatically maintained. Just as Terraform treats infrastructure as code, Vault treats secrets as managed resources with lifecycle, policies, and observability.
Understanding Vault's architecture is crucial for designing production deployments that meet security, availability, and performance requirements. Vault follows a client-server model where the Vault server manages all secrets operations while clients interact through a consistent API.
Core Architectural Components:
| Component | Responsibility | Key Characteristics |
|---|---|---|
| Storage Backend | Persistent storage for encrypted data | Pluggable (Consul, Raft, S3, etc.); handles durability, not security |
| Barrier | Encryption layer protecting storage | All data encrypted before storage; decryption requires unseal keys |
| Secret Engines | Generate, store, and manage secrets | Pluggable backends (KV, AWS, database, PKI, etc.) |
| Auth Methods | Verify client identity | Pluggable authentication (LDAP, OIDC, Kubernetes, cloud IAM) |
| Audit Devices | Record all operations | Multiple backends (file, syslog, socket); mandatory for compliance |
| System Backend | Internal Vault operations | Policies, leases, tokens, health, seal status management |
The Seal/Unseal Mechanism:
Vault implements a critical security feature through its seal mechanism. When a Vault server starts, it begins in a sealed state—all data remains encrypted and inaccessible. To unseal Vault, operators must provide a threshold of unseal keys (typically 3 of 5 shares using Shamir's Secret Sharing algorithm).
This design ensures that:
Master Key and Encryption Hierarchy:
1234567891011121314151617181920212223242526272829
┌─────────────────────────────────────────────────────────────┐│ DATA ENCRYPTION KEY ││ (256-bit AES-GCM, encrypts all stored data) │└───────────────────────────┬─────────────────────────────────┘ │ Encrypted by ▼┌─────────────────────────────────────────────────────────────┐│ MASTER KEY ││ (256-bit key, reconstructed during unseal) │└───────────────────────────┬─────────────────────────────────┘ │ Split using Shamir's Secret Sharing ▼┌─────────────────────────────────────────────────────────────┐│ UNSEAL KEYS ││ (N shares, threshold K required to reconstruct) ││ Example: 5 shares, 3 required (3-of-5) │└─────────────────────────────────────────────────────────────┘ Alternative: Auto-Unseal with Cloud KMS┌─────────────────────────────────────────────────────────────┐│ MASTER KEY ││ (Encrypted by cloud KMS instead of Shamir shares) │└───────────────────────────┬─────────────────────────────────┘ │ Protected by ▼┌─────────────────────────────────────────────────────────────┐│ CLOUD KMS (AWS KMS, GCP CKMS, etc.) ││ (Hardware-backed, IAM-controlled key access) │└─────────────────────────────────────────────────────────────┘While auto-unseal simplifies operations by eliminating manual unseal ceremonies, it shifts trust to your cloud provider's KMS. This is appropriate for most production environments but may not meet certain compliance requirements that mandate operator-controlled unseal processes. Understand your security posture before choosing.
Secret engines are the heart of Vault's flexibility. Each engine is a component that stores, generates, or transforms data. Engines are mounted at specific paths, and all operations on secrets go through the appropriate engine.
Vault ships with numerous built-in engines, each designed for specific use cases:
| Engine | Purpose | Use Cases |
|---|---|---|
| KV (Key-Value) | Store arbitrary secrets | API keys, configuration, static credentials |
| AWS | Generate dynamic AWS credentials | IAM users, STS tokens, assumed roles |
| Database | Generate dynamic database credentials | MySQL, PostgreSQL, MongoDB, Oracle users |
| PKI | Certificate authority operations | TLS certificates, client certs, code signing |
| Transit | Encryption-as-a-service | Data encryption, signing, verification |
| SSH | Generate SSH credentials | Signed SSH certificates, OTP access |
| TOTP | Time-based OTP generation | Multi-factor authentication tokens |
| Identity | Entity and group management | Cross-mount identity correlation |
The KV Secrets Engine - Versioned Secrets:
The KV (Key-Value) engine is the most commonly used engine, storing arbitrary key-value pairs. KV v2 introduces versioning, enabling you to:
1234567891011121314151617181920212223242526272829303132333435363738
# Enable KV v2 at a pathvault secrets enable -path=secret kv-v2 # Write a secret (creates version 1)vault kv put secret/myapp/database \ username="app_user" \ password="supersecret123" # Read current versionvault kv get secret/myapp/database # Update secret (creates version 2)vault kv put secret/myapp/database \ username="app_user" \ password="newsecret456" # Read specific versionvault kv get -version=1 secret/myapp/database # View metadata (all versions)vault kv metadata get secret/myapp/database # Soft delete current versionvault kv delete secret/myapp/database # Undelete (recover soft-deleted version)vault kv undelete -versions=2 secret/myapp/database # Permanently destroy a versionvault kv destroy -versions=1 secret/myapp/database # Delete all versions and metadatavault kv metadata delete secret/myapp/database # Configure version retentionvault write secret/metadata/myapp/database \ max_versions=10 \ delete_version_after="720h"Dynamic secrets represent Vault's most powerful capability and the feature that fundamentally differentiates it from simple secret storage systems. Rather than storing pre-existing secrets, dynamic secret engines generate secrets on-demand with automatic expiration.
Why Dynamic Secrets Matter:
Consider a traditional database credential workflow:
With dynamic secrets:
Database Secrets Engine Example:
The database secrets engine demonstrates dynamic secrets at their best. Vault connects to your database as a privileged user, then creates/revokes individual credentials on behalf of applications.
123456789101112131415161718192021222324252627282930
# Enable the database secrets enginevault secrets enable database # Configure the PostgreSQL connectionvault write database/config/production-postgres \ plugin_name=postgresql-database-plugin \ allowed_roles="readonly","readwrite","admin" \ connection_url="postgresql://{{username}}:{{password}}@postgres.prod:5432/appdb?sslmode=require" \ username="vault_admin" \ password="vault_admin_password" # Rotate the root credential (Vault now exclusively controls it)vault write -force database/rotate-root/production-postgres # Create a role for read-only accessvault write database/roles/readonly \ db_name=production-postgres \ creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \ GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \ revocation_statements="REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM \"{{name}}\"; DROP ROLE IF EXISTS \"{{name}}\";" \ default_ttl="1h" \ max_ttl="24h" # Create a role for read-write accessvault write database/roles/readwrite \ db_name=production-postgres \ creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \ GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \ default_ttl="1h" \ max_ttl="8h"For long-running applications, implement lease renewal before expiration. Request a short initial TTL (e.g., 1 hour), then renew every 30 minutes. This provides automatic credential rotation without connection disruption, while still limiting breach exposure if credentials leak.
Vault supports numerous authentication methods that allow clients to prove their identity. Each method is suited to different environments and use cases. The authentication process returns a Vault token with attached policies that determine what secrets the client can access.
Token-Based Authentication Model:
All Vault authentication ultimately results in a token. The token carries:
| Method | Best For | Identity Source |
|---|---|---|
| Token | Direct API access, initial setup | Pre-existing Vault token |
| AppRole | Machines, CI/CD pipelines | Role ID + Secret ID (two-factor for machines) |
| Kubernetes | Pods in Kubernetes clusters | Kubernetes service account JWT |
| AWS IAM | EC2 instances, Lambda functions | AWS instance identity or IAM credentials |
| GCP | GCE instances, Cloud Functions | GCP service account identity |
| Azure | Azure VMs, AKS | Azure managed identity |
| LDAP | Enterprise users | LDAP/Active Directory credentials |
| OIDC | SSO users, web applications | OpenID Connect provider (Okta, Auth0, etc.) |
| JWT/OIDC | Service-to-service, external JWTs | JWT from trusted issuers |
| Userpass | Development, simple setups | Username and password |
AppRole Authentication - The Machine Identity Standard:
AppRole is Vault's recommended method for authenticating machines and applications. It implements a two-factor authentication model:
This separation enables secure bootstrapping: the Role ID can be embedded in configuration, while the Secret ID is delivered through a separate, secure channel.
123456789101112131415161718192021222324252627282930313233343536
# Enable AppRole auth methodvault auth enable approle # Create a role for a specific applicationvault write auth/approle/role/payment-service \ token_policies="payment-service" \ token_ttl=1h \ token_max_ttl=4h \ secret_id_ttl=10m \ secret_id_num_uses=1 \ token_num_uses=0 \ bind_secret_id=true # Get the Role ID (can be stored in config)vault read auth/approle/role/payment-service/role-id# Role ID: abc123-def456-ghi789 # Generate a Secret ID (deliver securely to application)vault write -f auth/approle/role/payment-service/secret-id# Secret ID: xyz987-uvw654-rst321 # Application authenticates with bothvault write auth/approle/login \ role_id="abc123-def456-ghi789" \ secret_id="xyz987-uvw654-rst321" # Response contains token{ "auth": { "client_token": "hvs.CAESIJl...", "policies": ["default", "payment-service"], "token_type": "service", "renewable": true, "lease_duration": 3600 }}When running on Kubernetes, the Kubernetes auth method provides the cleanest integration. Pods automatically receive service account tokens that Vault can verify against the Kubernetes API. No secret delivery mechanism is needed—identity is derived from the infrastructure itself.
Vault's policy system controls what secrets and operations each authenticated identity can access. Policies are written in HCL (HashiCorp Configuration Language) and follow a deny-by-default model—everything is forbidden unless explicitly permitted.
Policy Syntax Fundamentals:
Policies define rules at specific paths with allowed capabilities:
123456789101112131415161718192021222324252627282930
# Allow reading secrets for a specific applicationpath "secret/data/myapp/*" { capabilities = ["read", "list"]} # Allow full management of database credentialspath "database/creds/myapp-role" { capabilities = ["read"]} # Allow renewing own tokenpath "auth/token/renew-self" { capabilities = ["update"]} # Allow looking up own token infopath "auth/token/lookup-self" { capabilities = ["read"]} #--------------------------------------------------# Capability Reference:# create - Create new data (POST to non-existing path)# read - Read data (GET)# update - Modify existing data (POST/PUT)# delete - Delete data (DELETE)# list - List keys at path (LIST)# sudo - Access root-protected paths# deny - Explicitly forbid (overrides other rules)#--------------------------------------------------Design policies with least privilege: start restrictive and add permissions as needed. Use path templating to reduce policy sprawl. Avoid wildcards at path roots (e.g., 'secret/*'). Regularly audit policies as requirements change. Remember that deny always wins over allow in policy evaluation.
Policy Attachment:
Policies are attached to tokens through authentication methods. When configuring an auth method role, you specify which policies apply:
# AppRole with specific policies
vault write auth/approle/role/payment-service \
token_policies="payment-secrets,database-readonly,common"
# Kubernetes auth role with policies
vault write auth/kubernetes/role/api-server \
policies="api-secrets,transit-encrypt"
When a client authenticates, their token inherits the policies defined for their authentication role, creating a clear mapping from identity to permissions.
Production Vault deployments must address availability, disaster recovery, performance, and operational concerns. Vault supports multiple storage backends with different HA characteristics.
Integrated Raft Storage (Recommended):
Vault's integrated Raft storage has become the recommended approach for most deployments. It provides:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
# Production Vault configuration with Raft storagestorage "raft" { path = "/vault/data" node_id = "vault-1" # Performance tuning performance_multiplier = 1 # Retry configuration for cluster join retry_join { leader_api_addr = "https://vault-2.example.com:8200" } retry_join { leader_api_addr = "https://vault-3.example.com:8200" }} # Listener configurationlistener "tcp" { address = "0.0.0.0:8200" tls_cert_file = "/vault/certs/vault.crt" tls_key_file = "/vault/certs/vault.key" tls_min_version = "tls12" # Enable request logging telemetry { unauthenticated_metrics_access = false }} # Cluster communicationcluster_addr = "https://vault-1.example.com:8201"api_addr = "https://vault-1.example.com:8200" # Auto-unseal with AWS KMSseal "awskms" { region = "us-west-2" kms_key_id = "alias/vault-unseal"} # Telemetry for monitoringtelemetry { prometheus_retention_time = "30s" disable_hostname = true} # Audit logging (mandatory for compliance)audit { file "file" { path = "/vault/logs/audit.log" log_raw = false mode = "0600" }} # UI accessui = true # Default lease settingsdefault_lease_ttl = "1h"max_lease_ttl = "24h" # Disable memory locking (required for containers, enable if on dedicated VM)disable_mlock = true # Log levellog_level = "info"Regularly test disaster recovery procedures. Take Raft snapshots before any upgrades. Store recovery keys and root tokens securely (ideally in separate secure storage like hardware security modules). Document runbooks for common operational scenarios including complete cluster recovery.
HashiCorp Vault represents the gold standard in secrets management, providing a comprehensive platform that addresses the full lifecycle of secrets in modern infrastructure. Let's consolidate the key concepts:
What's Next:
With a deep understanding of HashiCorp Vault's architecture and capabilities, the next page explores AWS Secrets Manager—Amazon's managed secrets service. You'll learn how it compares to Vault, when to choose one over the other, and how to leverage AWS-native secrets management for cloud-centric workloads.
You now have a comprehensive understanding of HashiCorp Vault's architecture, secret engines, authentication methods, policies, and production deployment patterns. This knowledge forms the foundation for comparing and evaluating other secrets management solutions in the following pages.