Vault access control is decided by the Capabilities you grant inside a policy. It looks like plain CRUD on the surface, but it actually has its own rules around evaluation order and sudo protection, and shows up constantly in both the exam and real-world work.
Based on the official documentation, this article covers create/read/update/delete/list/sudo/deny end-to-end: least-privilege design, wildcard usage, and verification commands.
Vault policies define permissions by granting Capabilities per path. The main ones are create, read, update, delete, list, sudo, and deny. Evaluation sums the capabilities from all matching policies, and if even one deny is present, the request is unconditionally rejected.
sudo is a privileged capability required for certain administrative endpoints (such as those under sys/) that ordinary read/write cannot reach. list is a dedicated listing capability and is separate from read.
| Capability | Primary Use | Typical CLI / API Example | Notes |
|---|---|---|---|
| create | Writes that create new resources | vault kv put secret/app k=v (new) | Some backends require update to be granted alongside |
| read | Retrieving a value | vault kv get secret/app | Does not substitute for list |
| update | Updating writes | vault write auth/userpass/users/alice password=... | Used as the de facto write permission for many endpoints |
| delete | Deletion | vault kv delete secret/app | Some engines split soft delete and destroy into separate endpoints |
| list | Key listing | vault kv list secret/ | LIST-only. read alone cannot enumerate keys |
| sudo | Administrative operations | vault auth enable userpass, vault secrets enable kv | Required for sudo-protected paths like sys/; must be paired with create/update etc. |
Capability evaluation flow (simplified)
Least-privilege policy example (HCL)
path "secret/data/app/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
# Deny a specific subpath explicitly (deny always wins)
path "secret/data/app/prod/*" {
capabilities = ["deny"]
}
# For administrative operations (under sys/, needs sudo)
path "sys/auth/*" {
capabilities = ["sudo", "create", "read", "update", "delete", "list"]
}The biggest gotcha is that listing uses list and reading uses read, and the two are separate. Having read does not let you list paths, and having only list does not let you read values.
Write operations may split between create and update depending on the implementation. Check the target backend's requirements at design time, and when in doubt, grant create and update as a set. Deletion requires delete.
Typical CLI operations and required permissions
# Create and update
vault kv put secret/app api_key=abc123
# Read
vault kv get secret/app
# Delete
vault kv delete secret/app
# List: mind the trailing slash
vault kv list secret/
# Check what your own token can do on a given path
vault token capabilities secret/data/appVault policies are evaluated per path, and when multiple path blocks match, the capabilities are summed. The longest match wins, but deny always takes top priority and rejects the request.
Combine broad wildcards with narrow exception rules (such as deny) to balance team-level delegation with blocking sensitive subpaths.
Combining wildcards with exception rules
# Team A gets full rights under team-a/
path "secret/data/team-a/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
# But the production subpath is denied explicitly
path "secret/data/team-a/prod/*" {
capabilities = ["deny"]
}
# A general viewer who should only be able to list
path "secret/data/*" {
capabilities = ["list"]
}Administrative operations such as enabling/disabling secret engines and auth methods run against endpoints under sys/ and require sudo. sudo alone is not enough — pair it with create/update/read/delete according to the target operation.
For operator policies, grant sudo only on the narrow sys/ paths covering the operator's scope, and use it with the shortest-lived tokens possible for safety.
Operator policy and execution example
# Managing auth methods
path "sys/auth/*" {
capabilities = ["sudo", "create", "read", "update", "delete", "list"]
}
# Managing secrets engines
path "sys/mounts/*" {
capabilities = ["sudo", "create", "read", "update", "delete", "list"]
}
# Enable an auth method (example)
vault auth enable userpass
# Enable the KV engine (example)
vault secrets enable -path=secret kvWhen permissions are not working as expected, start by checking your own token's capabilities. Use the CLI vault token capabilities command or the sys/capabilities-self API to get the evaluation result instantly.
To avoid information leakage, Vault sometimes returns 404 when permissions are insufficient. Because this makes it hard to distinguish missing resources from missing permissions, checking capabilities directly is the most effective approach.
Verification command examples
# Evaluate the path for the token you are logged in with
vault token capabilities secret/data/app
# Evaluate for a specific token instead
vault token capabilities s.XXXXXXXX secret/data/app
# Check the capabilities of your own token over the API
curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"paths":["secret/data/app"]}' \
$VAULT_ADDR/v1/sys/capabilities-selflist and read are separate; listing always requires list. deny always takes top priority — even a single occurrence anywhere rejects the request. sudo is required for administrative paths like sys/ and must be granted together with create/update etc., not alone.
Wildcards, longest match, summing across multiple policies, and verification via capabilities-self are recurring exam themes. Follow least privilege by keeping paths narrow, and override exceptions with deny or with more specific paths.
Minimal verification policy (smallest example aligned to the checklist)
# Read plus list only
path "secret/data/app/*" {
capabilities = ["read", "list"]
}
# Grant administrative operations narrowly, via a separate policy
path "sys/auth/userpass" {
capabilities = ["sudo", "create", "read", "update"]
}Associate
Question 1
You need to let a user enumerate the key names under a secret path and read individual values, but not write or delete. Which combination of capabilities should the policy grant?
Correct answer: A
Enumeration requires list and value retrieval requires read. read alone cannot enumerate; create/update are for writes and delete is for deletion, so they fall outside the requirement.
How should I choose between create and update?
Endpoint implementations vary in what they require, so for write operations it is safest to grant create and update together. If you strictly want to allow new creation only, check the target backend's requirements and narrow the grant as much as possible.
What goes wrong without list? Is read alone enough?
list is a dedicated listing capability and cannot be substituted by read. Without list, you cannot enumerate which keys exist underneath a path. For browsing operations, grant read and list together.
What are the best practices for deny?
Use deny for exception control, such as pinpoint-blocking sensitive subpaths under a broad allow. Since deny takes top priority, check it together with longest-prefix matching during design and debugging to avoid unintended denials.
Practice with certification-focused question sets
Try free questionsNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
Vault Core Concepts: Sealed/Unsealed, Auth, Secrets (2026)
Vault fundamentals — sealed/unsealed state, auth methods, se...
Vault Operations Professional (VOP-003): Complete Guide (2026)
Pass the Vault Operations Professional exam — enterprise pat...
Vault Path-Based Routing: API URL Structure (2026)
How Vault's path-based routing works — mount points, sub-pat...
Vault Tokens: Auth Token Mechanics (2026)
Token fundamentals — service vs. batch tokens, accessor, ren...
Vault Token Types: Service, Batch, Periodic (2026)
Service vs. batch tokens compared — performance, ACL behavio...