Identities, entities & templated policies
The entity/alias model, groups, and ACL templating that scales.
At scale, the thing that breaks first is not storage or crypto — it is policy sprawl. If every team, app, and environment needs its own hand-written rules, you end up with thousands of near-identical policies that nobody can audit. The fix is a proper identity model plus policy templating: represent every human and workload as one identity regardless of how they logged in, then write a small number of policies that adapt to that identity at request time.
Entities and aliases: one identity, many logins
Vault’s identity system separates the person or workload (an entity) from the ways they authenticate (aliases). A developer who logs in via OIDC in the morning and via a CLI token later is one entity with two aliases; a service that authenticates via Kubernetes in one cluster and AWS in another is still one entity. This matters because policy, metadata, and audit attribution attach to the entity — so "what can Alice do" and "everything Alice touched" are answerable across every auth method, and disabling the entity cuts off all of them at once.
Templated policies: one rule, every tenant
Policy templating lets a path in a policy contain identity variables that are substituted per request. Instead of writing one policy per team that grants access to that team’s path, you write a single policy whose path is parameterized by the caller’s identity — and it is mathematically impossible for it to grant cross-tenant access, because the path always resolves to the caller’s own space. This collapses thousands of policies into one and removes the copy-paste mistakes that leak tenants into each other.
# each identity can only ever reach its own tree — no per-user policy neededpath "secret/data/users/{{identity.entity.id}}/*" {capabilities = ["create", "read", "update", "delete", "list"]}# group-scoped shared space, keyed by an IdP-mapped group name:path "secret/data/teams/{{identity.groups.names.0}}/*" {capabilities = ["read", "list"]}# the path resolves at request time to the caller; cross-tenant access is impossible.
Groups from your IdP, not in Vault
The scalable source of truth for "who is on which team" is your identity provider, not Vault. External groups map an IdP claim (an Okta or Entra group, an OIDC groups claim) to a Vault group that carries policy, so access follows joiners, movers, and leavers automatically — someone removed from the "payments" group in the IdP loses the payments policy on their next login with no Vault change. This is how you keep least privilege true over time instead of accumulating stale grants nobody remembers to remove.