Understanding the /data Segment in HashiCorp Vault Policy Paths (KV v2)
Introduction
When working with HashiCorp Vault’s key‑value (KV) secrets engine, you’ll often see the term /data appear in policy definitions but not when you read or write a secret via the API or CLI. This apparent inconsistency can be confusing for newcomers to Vault, especially when configuring ACL policies for the KV version 2 (KV v2) secrets engine.
In this article we’ll explain why the /data prefix is required in policy paths, how KV v2 stores secrets internally, and how to write policies that correctly grant access without causing permission errors. Real‑world examples and a quick FAQ will help you apply the concepts to your own Vault deployments.
1. KV v2 vs. KV v1 – What Changed?
| Feature | KV v1 | KV v2 |
|---|---|---|
| Versioning | No version history | Full versioning of each secret |
| Data layout | Simple key/value store | Separate metadata and data endpoints |
| API paths | secret/<path> |
secret/data/<path> (read/write) and secret/metadata/<path> (metadata) |
| Policy paths | secret/* |
secret/data/* (data) and secret/metadata/* (metadata) |
KV v2 introduces versioned secrets, which means Vault must distinguish between the data of a secret (the actual key/value pairs) and the metadata (creation time, version numbers, deletion status, etc.). To keep this separation clean, the engine mounts two logical sub‑paths:
/data– used for reading and writing the secret’s payload./metadata– used for operations that affect the secret’s version history (e.g.,delete,destroy,list).
Because policies are evaluated before the request reaches the engine, the policy path must match the exact internal route Vault expects. That is why /data (or /metadata) appears in ACL rules even though the CLI or API shortcuts hide it from the user.
2. How Policies Are Evaluated
- Client request – The user issues
vault kv get secret/foo. - Vault routing – Internally the KV v2 engine rewrites the request to
secret/data/foo. - ACL check – Vault looks for a policy rule that matches the rewritten path (
secret/data/foo). - Decision – If a rule permits the operation, Vault proceeds; otherwise it returns a permission error.
Because step 2 happens before the ACL check, your policy must reference the rewritten path (/data), not the user‑facing shortcut.
3. Writing Correct Policy Paths
3.1 Basic Read‑Only Policy
# Allow reading any secret under the "app" namespace
path "secret/data/app/*" {
capabilities = ["read", "list"]
}
Note: No metadata capability is needed for simple reads, so we omit secret/metadata/app/*.
3.2 Full‑Control Policy (Read, Write, Delete)
# Full CRUD on the "prod" namespace
path "secret/data/prod/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret/metadata/prod/*" {
capabilities = ["delete", "destroy", "list"]
}
Explanation
create,update,deleteapply to the data endpoint.deleteanddestroyon the metadata endpoint let you remove specific versions or permanently erase a secret.
3.3 Using Wildcards Wisely
*matches a single path segment.**(double‑asterisk) matches any number of nested segments (available in Vault 1.9+).
Example for a deep hierarchy:
path "secret/data/team/**" {
capabilities = ["read", "list"]
}
4. Practical Example: Lab Scenario
Scenario: A CI/CD pipeline needs to read the database credentials stored at secret/data/cicd/db. It must not be able to modify or delete them.
Policy:
path "secret/data/cicd/db" {
capabilities = ["read"]
}
CLI usage (no /data needed):
# The user runs this command
vault kv get cicd/db
# Internally Vault maps to secret/data/cicd/db and matches the policy above.
If the same policy mistakenly omitted /data:
# Incorrect policy – will never match
path "secret/cicd/db" { capabilities = ["read"] }
The pipeline would receive a permission denied error because the ACL engine never sees a matching rule.
5. Common Questions & Tips
Q1: Do I need /metadata in every policy?
A: Only when you intend to manage secret versions (e.g., delete specific versions, destroy a secret, or list version history). For simple read/write operations, /metadata is unnecessary.
Q2: Can I hide /data from the policy by using a wrapper script?
A: No. ACL evaluation happens before any client‑side logic. The policy must reflect the internal path structure.
Q3: What happens if I mount the KV engine at a custom path?
A: Replace secret with your mount point. For a mount at kv2, the policy path becomes kv2/data/... and kv2/metadata/....
Q4: Is /data required for KV v1?
A: No. KV v1 does not have separate data/metadata endpoints, so the policy path is simply secret/*.
Tips for Writing Clean Policies
- Group related paths using a single block with a wildcard (
*or**). - Separate data and metadata rules to follow the principle of least privilege.
- Document the mount point in your policy comments to avoid confusion when the engine is remounted.
- Test policies with
vault policy read <name>andvault read sys/policy/<name>before applying them to production.
6. Quick Reference Cheat Sheet
| Action | API/CLI (user) | Internal path | Policy path needed |
|---|---|---|---|
| Read secret | vault kv get <path> |
secret/data/<path> |
secret/data/<path> |
| Write secret | vault kv put <path> key=val |
secret/data/<path> |
secret/data/<path> |
| List secrets | vault kv list <path> |
secret/data/<path> (list) |
secret/data/<path> |
| Delete version | vault kv delete -versions=2 <path> |
secret/metadata/<path> |
secret/metadata/<path> |
| Destroy secret | vault kv destroy -versions=2 <path> |
secret/metadata/<path> |
secret/metadata/<path> |
Conclusion
The /data segment in HashiCorp Vault policy paths is not an optional convenience—it is a required part of the internal routing for KV v2. Understanding that policies are evaluated against the rewritten request path explains why you include /data (and optionally /metadata) in ACL rules, while the same segment is omitted from everyday read/write commands. By aligning your policies with Vault’s internal structure, you avoid permission errors and enforce the principle of least privilege across your secret management workflows.
For more details, refer to the official documentation: https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v2#acl-rules.