Fix Vault 'permission denied' on Secret Read
The Error
You attempt to read a secret from Vault and get:
Error reading secret/data/myapp/config: Error making API request.
URL: GET https://vault.example.com/v1/secret/data/myapp/config
Code: 403. Errors:
* 1 error occurred:
* permission denied
This is one of the most common Vault errors and usually comes down to a mismatch between your token's attached policies and the actual path you are trying to access.
Root Cause
Vault uses a policy-based ACL system. Every token has one or more policies attached, and each policy defines which paths the token can access and what operations (read, write, list, delete) are allowed. The "permission denied" error means:
- Your token does not have a policy granting
readon the requested path. - The policy exists but targets a different path (often a KV v1 vs v2 path mismatch).
- The token has expired or been revoked.
- The secret engine is mounted at a different path than you expect.
Step-by-Step Fix
1. Check your current token
vault token lookup
Look at the policies field. Confirm the expected policy name is listed. Also check expire_time to make sure the token is still valid.
2. Inspect the policy
vault policy read my-app-policy
Look at the path rules. A common mistake with KV v2 is forgetting the data/ segment:
# WRONG for KV v2 - this won't work
path "secret/myapp/*" {
capabilities = ["read", "list"]
}
# CORRECT for KV v2
path "secret/data/myapp/*" {
capabilities = ["read", "list"]
}
3. Verify the secret engine mount
vault secrets list
Confirm the engine is mounted where you think it is. If your KV engine is mounted at kv/ instead of secret/, your policy paths need to reflect that.
4. Test with a broader policy (temporarily)
Create a debug policy to confirm the issue is ACL-related:
# debug-policy.hcl
path "secret/*" {
capabilities = ["read", "list"]
}
vault policy write debug-policy debug-policy.hcl
vault token create -policy=debug-policy
Use the new token to test the read. If it works, the problem is definitely in your original policy's path definition.
5. Fix and apply the corrected policy
vault policy write my-app-policy my-app-policy.hcl
Existing tokens using this policy will pick up changes immediately; no token regeneration is needed.
6. If using Vault Agent or AppRole
Check that the role has the correct policies attached:
vault read auth/approle/role/my-app-role
Look at token_policies and update if needed:
vault write auth/approle/role/my-app-role token_policies="my-app-policy"
Prevention Tips
- Use KV v2 paths consistently. Always include
data/for reads andmetadata/for listing when using KV v2. - Test policies with
vault token capabilities. Runvault token capabilities secret/data/myapp/configto see exactly what your current token can do on a path. - Automate policy deployment. Store policies in version control and deploy them via CI/CD so drift between environments is caught early.
- Set up Vault audit logging. Enable the file or syslog audit backend so denied requests are logged with the exact path and token accessor for fast debugging.
Was this article helpful?
Senior Kubernetes Architect
10+ years orchestrating containers in production. Battle-tested opinions on everything from pod scheduling to service mesh. I've seen clusters burn and helped rebuild them better.
Related Articles
Vault Token Renewal Failing: Fixing "token Is Not Renewable" And TTL Expiry Issues
If you've ever stared at a production alert screaming `token is not renewable` at 2 AM, you know the particular joy of Vault token management. These errors...
Fix Vault 'Sealed' Status After Restart
How to handle HashiCorp Vault entering sealed state after a restart, including manual unseal, auto-unseal configuration, and HA considerations.
Vault Kubernetes Authentication: Injecting Secrets into Pods Without Hardcoding
Set up Vault's Kubernetes auth method so pods authenticate using their ServiceAccount tokens — then inject secrets via Vault Agent sidecar or the Vault Secrets Operator. Zero hardcoded credentials in your cluster.
HashiCorp Vault: Secrets Management from First Run to Production
How to set up and use HashiCorp Vault for secrets management — KV secrets engine, dynamic credentials, policies, AppRole authentication, and production hardening. Stop hardcoding credentials in environment variables.
Vault Dynamic Secrets: Short-Lived Credentials on Demand
Generate short-lived database credentials, AWS IAM roles, and PKI certificates with Vault dynamic secrets — eliminating long-lived credentials from your infrastructure.
HashiCorp Vault Fundamentals: Installation and First Secrets
Install HashiCorp Vault, understand seal/unseal mechanics, configure secret engines, and store your first secrets with policies and authentication methods.
More in Vault
View all →Vault with Kubernetes: Injecting Secrets into Pods
Inject HashiCorp Vault secrets into Kubernetes pods using the Agent Injector and CSI provider — with practical examples for database credentials and TLS certificates.
Vault in Production: HA, Auto-Unseal, and Disaster Recovery
Deploy Vault for production — HA with Raft storage, auto-unseal with cloud KMS, audit logging, performance tuning, backup strategies, and disaster recovery.