DevOpsil
Vault
85%
Needs Review

Fix Vault 'permission denied' on Secret Read

Aareez AsifAareez Asif3 min 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:

  1. Your token does not have a policy granting read on the requested path.
  2. The policy exists but targets a different path (often a KV v1 vs v2 path mismatch).
  3. The token has expired or been revoked.
  4. 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 and metadata/ for listing when using KV v2.
  • Test policies with vault token capabilities. Run vault token capabilities secret/data/myapp/config to 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.
Share:

Was this article helpful?

Aareez Asif
Aareez Asif

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

VaultQuick RefBeginnerNeeds Review

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.

Sarah Chen·
3 min read

More in Vault

View all →

Discussion