ACL policies that scale
Path capabilities, identity, and least privilege.
In short. Authentication answers who you are. ACL policies answer what you may touch. A Vault cluster with open policies is a fancy database of secrets with a login screen.
Authentication answers who you are. ACL policies answer what you may touch. A Vault cluster with open policies is a fancy database of secrets with a login screen. Production policies are small, path-scoped capability lists assigned through roles and identity groups — not a single admin policy stapled onto every human token.
Vault policies are authored in HCL (or JSON) and written to sys/policy. Each path lists capabilities such as read, create, update, delete, list, and sudo. Deny is the default: if no policy grants a capability on a path, the request fails. That default is the whole security model.
Write least privilege on real paths
KV v2 data lives under secret/data/... while metadata lives under secret/metadata/.... Granting only secret/data/app/* without list on metadata is a common surprise. Database credential minting is database/creds/role-name. PKI issue paths are pki_int/issue/role-name. Read the engine docs for the exact path shape before you invent wildcards.
vault policy write app-webapp -<<'EOF'path "secret/data/webapp/*" {capabilities = ["read"]}path "database/creds/webapp-rw" {capabilities = ["read"]}path "auth/token/renew-self" {capabilities = ["update"]}EOFvault policy read app-webapp
path "secret/data/webapp/*" {capabilities = ["read"]}...
Attach policies via auth roles (token_policies) and via identity groups so IdP group membership flows into Vault without editing every user. Prefer group-attached policies for humans and tight role policies for machines. Avoid path "*" except on break-glass policies that should almost never be assigned.
Identity entities and tidy ownership
When a person logs in through OIDC and a workload through Kubernetes, Vault can map both to identity entities and groups. Templated policies (covered deeper in the advanced course) can scope paths per entity. Even without templates, naming policies after applications (app-payments, app-webapp) beats naming them after people (alice-admin).
Operational hygiene
Store policies in Git and apply them with CI using a limited GitOps token. Review diffs like code. Alert on policy writes in the audit log. Periodically list tokens and accessors; revoke orphans. A policy that grants sudo on sys/* is root in slow motion — treat it that way.
Try this
Create a narrow policy, assign it to a token, prove a permitted read works and a neighboring path fails.
vault token create -policy=app-webapp -ttl=15mexport VAULT_TOKEN=<token>vault kv get secret/webapp/configvault kv get secret/other/config
====== Data ======...allowed...Error making API request...* permission denied# SUCCESS — default deny on the neighbor path
Takeaway
Policies are the real authorization layer: default deny, path-accurate capabilities, group-driven assignment. Auth without policy is an unlocked door with a visitor log.
Next: store the static secrets you still need in KV v2 with versioning and check-and-set.