Cloud Security Wire
AWS Azure GCP RSS
AWSAzureGCPMulti-Cloud Misconfiguration critical

HashiCorp Vault: Misconfiguration Attack Paths and Secrets Management Hardening

HashiCorp Vault is widely deployed as a centralised secrets management platform, but misconfigurations in token handling, auth method setup, and ACL policies create high-impact attack paths. This guide covers the principal Vault misconfigs, exploitation chains, and hardening steps.

By Cloud Security Wire · ·
#HashiCorp Vault#secrets management#token abuse#AppRole#ACL policy#privilege escalation#Kubernetes auth#cloud security#secrets sprawl#hardening
Critical Severity

This issue has been assessed as critical severity. Review affected configurations immediately.

HashiCorp Vault has become the de facto standard for centralised secrets management in enterprise and cloud-native environments. A single Vault cluster may hold database credentials, cloud provider API keys, TLS certificates, SSH signing keys, and application service secrets for hundreds of services. That centralisation is the point — it provides a single auditable source of truth for secrets rather than secrets sprawled across environment variables, config files, and CI/CD pipeline variables.

It also means that a misconfigured Vault instance, or compromised access to Vault, can expose an entire organisation’s credential inventory in a single breach. The attack paths through Vault misconfigurations are well-understood. Many are exploitable within minutes of gaining initial access to a cloud environment where Vault is deployed.

The Root Token Problem

Every Vault initialisation produces a root token. The root token has unlimited access to every Vault path and operation — there are no ACL policies that apply to it, no restrictions of any kind. It exists to bootstrap initial Vault configuration before other auth methods are set up.

The intended use: generate the root token, set up auth methods and ACL policies, then revoke the root token. The token should not persist in production.

The common misuse: the root token is generated, configuration is completed, but the token is never revoked. It lives in a Terraform state file, an environment variable in a deployment pipeline, a developer’s .env file, or a secrets manager entry (sometimes in Vault itself). Attackers who find a Vault root token — through source code scanning, environment variable enumeration, or Terraform state file access — have complete Vault access.

Check: vault token lookup against the token will reveal its policies. A token with root policy is the root token.

Remediate: Revoke the root token post-setup. Generate a new root token only when needed for emergency operations, via the vault operator generate-root process, and immediately revoke it after use. Audit your Terraform state files, CI/CD environment variables, and secrets stores for any stored root token values.

AppRole Auth Method Misconfiguration

AppRole is the recommended Vault auth method for machine-to-machine authentication. Applications authenticate using a role_id (a stable identifier for the role) and a secret_id (a rotating one-time or short-lived credential). The security model depends on both values being required — the role_id alone is insufficient.

The common misconfigurations:

Storing role_id and secret_id together in the same location eliminates the separation of duties the AppRole model is designed to provide. If both are in the same environment variable block, config file, or CI/CD variable group, a single exposure compromises the authentication mechanism entirely.

Long-lived or non-rotated secret_id values undermine the one-time-use design. AppRole supports secret_id_ttl and secret_id_num_uses parameters. Setting secret_id_num_uses = 0 (unlimited) and secret_id_ttl = 0 (never expires) means a single compromised secret_id provides indefinite access.

Overly permissive AppRole policies are the most impactful misconfiguration. If an AppRole used by a low-trust application is granted a policy that allows reading across broad Vault paths rather than just the specific secrets that application needs, lateral movement through Vault is achievable from any compromised workload using that role.

Remediation checklist:

# Review existing AppRole configurations
vault list auth/approle/role

# Check specific role parameters
vault read auth/approle/role/<role-name>

# Key fields to review:
# secret_id_ttl: should not be 0 (never expiring)
# secret_id_num_uses: should match application needs (1 for CI/CD, limited for long-running services)
# policies: should follow least privilege — only required paths
# token_ttl / token_max_ttl: should be short-lived

Kubernetes Auth Method Attack Paths

In Kubernetes environments, Vault’s Kubernetes auth method allows pods to authenticate using their service account JWT tokens. The Vault server validates the JWT against the Kubernetes API to confirm the token’s legitimacy, then issues a Vault token with mapped policies.

Misconfigured token reviewer binding: Vault needs a Kubernetes service account with permission to call the TokenReview API. If this service account has excessive RBAC permissions beyond TokenReview, an attacker who compromises Vault’s Kubernetes service account has elevated cluster privileges.

Pod identity escape: In default configurations, Vault Kubernetes auth maps based on the service account name and namespace. If a Vault role’s bound_service_account_names is set to * (wildcard) and bound_service_account_namespaces is also wildcard or set to privileged namespaces, any pod in the cluster can authenticate as that Vault role.

Examine role bindings:

vault read auth/kubernetes/role/<role-name>
# Review:
# bound_service_account_names: should be specific, not "*"
# bound_service_account_namespaces: should be specific namespaces
# policies: should be least-privilege

Service account token projection: By default, Kubernetes service account tokens projected into pods are valid for extended periods and valid for any audience. Using expirationSeconds in pod specs and audience-restricted tokens limits the window of opportunity if a token is exfiltrated.

ACL Policy Weaknesses

Vault ACL policies use HCL or JSON to define which paths a token can access and with which capabilities (read, write, list, delete, sudo). Common weaknesses:

Wildcard path permissions grant access to unintended secrets:

# Overly broad — grants access to all secrets in the kv mount
path "secret/*" {
  capabilities = ["read", "list"]
}

# Correct — grants access only to the specific path this application needs
path "secret/data/myapp/database" {
  capabilities = ["read"]
}

sudo capability on sensitive paths allows token operations (token creation, revocation, policy manipulation) that enable privilege escalation within Vault. Unless a role specifically requires it, sudo should not appear in ACL policies.

sys/ path access grants meta-level control over Vault itself — mount management, audit log management, policy management. Applications should never have access to sys/ paths.

Audit your policies:

# List all policies
vault policy list

# Review a specific policy
vault policy read <policy-name>

Database Secrets Engine: Dynamic Credentials

The database secrets engine is one of Vault’s most powerful security features: it generates short-lived database credentials on demand, eliminating long-lived database passwords. When misconfigured, it becomes an attack amplifier.

Static roles vs dynamic roles: Static roles have a single username with a rotating password — the credentials are long-lived (though Vault rotates the password on a schedule). Dynamic roles create new users for each credential request and delete them after TTL expiry. For most use cases, dynamic roles provide stronger isolation.

Long TTLs on dynamic credentials reduce the security benefit. A dynamic credential with a 72-hour TTL provides similar exposure to a static credential if the issuing application is compromised.

Connection URL exposure: The database secrets engine requires Vault to have a privileged connection to your database. This connection is stored in Vault. A token with read access to database/config/<connection-name> can reveal the root database credential Vault uses for administration. Ensure policies for application roles do not include access to database/config/ paths — only database/creds/ paths.

Transit Engine and Encryption-as-a-Service

The Vault transit engine provides encryption-as-a-service, allowing applications to encrypt and decrypt data without handling encryption keys directly. Misconfigurations here affect data confidentiality rather than credential access.

Exportable keys: By default, Vault transit keys cannot be exported. If a transit key is created with exportable = true, any token with access to that key path can export the raw cryptographic material and use it outside Vault. Unless there is a specific technical requirement to export the key (rare), all transit keys should be non-exportable.

Insufficient key rotation: The transit engine supports key versioning and rotation. Minimum-encryption-version controls which key versions can be used for new encryptions. If old key versions remain usable for encryption indefinitely, ciphertext rotation — re-encrypting data with a newer key version — provides no security benefit. Set a min_encryption_version policy and rotate keys on a schedule.

Audit Logging

Vault’s audit log is the primary tool for detecting credential abuse and misconfiguration. If audit logging is not enabled, there is no record of who accessed which secrets.

# Check if audit logging is enabled
vault audit list

# Enable file audit log (also consider syslog or socket to SIEM)
vault audit enable file file_path=/var/log/vault/audit.log

Audit logs should be shipped to a SIEM and alerts configured for: root token usage, policy changes, new mount creation, failed authentication spikes, and access to high-value paths outside normal application access patterns. Vault generates structured JSON audit events that are straightforward to parse and alert on.

← All Analysis Subscribe via RSS