hashicorp/vault
Policy and ACL
Vault's authorization layer compiles HCL policies into in-memory ACL trees and checks every request against them. Source: vault/policy.go (17k lines), vault/policy_store.go (30k lines), vault/acl.go (28k lines).
Purpose
Enforce capability checks: given a token's policies, is the requested operation on this path allowed?
Concepts
- Policy: a named, namespaced HCL document that grants or denies capabilities on path patterns.
- Capability: one of
read,list,create,update,delete,sudo,deny,patch,subscribe,recover,recover-prefix. - ACL: the merged in-memory representation of a token's policies. Built per request from the token's effective policy list.
Directory layout
vault/
├── policy.go # Parser for HCL policy text
├── policy_store.go # CRUD for stored policies, including ACL/RGP/EGP
├── policy_store_util.go
├── policy_util.go
├── acl.go # ACL struct + capability checks
├── acl_ce.go, acl_util.go # CE stubs
├── capabilities.go # Computed capability list for a path
├── password_policy_util.go # Vault password policies (different concept)
└── ...Key abstractions
| Symbol | File | Description |
|---|---|---|
Policy |
vault/policy.go |
Parsed policy with paths and capabilities. |
PathRules |
vault/policy.go |
One rule for a path pattern. Has Capabilities, AllowedParameters, DeniedParameters, MFAMethods, ControlGroup. |
PolicyStore |
vault/policy_store.go |
Stores policies; also handles RGP/EGP (Enterprise role/endpoint governing policies). |
ACL |
vault/acl.go |
Compiled, per-request authorization tree. |
ACL.AllowOperation |
vault/acl.go |
Hot-path capability check. |
ACL.Capabilities |
vault/acl.go |
List capabilities at a path; used by sys/capabilities. |
Sample policy
path "secret/data/team/*" {
capabilities = ["read", "create", "update", "delete", "list"]
}
path "sys/auth/*" {
capabilities = ["create", "update", "delete", "sudo"]
}
path "sys/policy/*" {
capabilities = ["deny"]
}* matches any single segment, + matches a single segment with no boundary, and a trailing * matches any continuation. Glob behavior is documented in vault/policy.go.
Compilation flow
graph LR
HCL[Policy HCL text] --> Parser[vault/policy.go ParseACLPolicy]
Parser --> Rules[Policy{Paths: []*PathRules}]
Rules --> Store[(policy_store.go)]
TokenPolicies[Token + identity policies] -->|merge by name| ACLBuild[NewACL]
Store --> ACLBuild
ACLBuild --> ACL[in-memory ACL]
Req[Request path + op] --> Check[ACL.AllowOperation]
ACL --> Check
Check --> Decision[Allowed / Denied / Wrap]NewACL builds a tree where each node holds the merged capabilities for a path prefix. AllowOperation walks the tree, picking the most specific match (with deny short-circuiting).
Per-path constraints
A PathRules entry can carry more than just a list of capabilities:
allowed_parameters/denied_parameters: restrict which body fields a caller can set.required_parameters: force certain fields to be present.min_wrapping_ttl/max_wrapping_ttl: bound response wrapping TTL.mfa_methods: require login MFA on this path.control_group(Enterprise): require multi-party authorization.
Sentinel and Enterprise extensions
PolicyStore also stores RGP (Role Governing Policies) and EGP (Endpoint Governing Policies) — Sentinel programs that run in addition to ACL. The Sentinel engine itself is closed-source; OSS only carries the storage and dispatch.
Integration points
- Loaded by
Core.setupPolicyStoreafter unseal. - Looked up per-request in
Core.checkToken(vault/request_handling.go). - Surfaced via
sys/policy,sys/policies/acl,sys/policies/rgp,sys/policies/egpinvault/logical_system.go. - The CLI surface (
vault policy ...) is incommand/policy*.go.
Entry points for modification
- Add a new capability: extend the parser (
vault/policy.go) and the matcher (vault/acl.go). Updatevault/capabilities.gososys/capabilities-selfreports it. - Add a new path constraint: extend
PathRulesinvault/policy.goand apply it inACL.AllowOperation. - Tweak template inheritance for namespaces: see
vault/policy.go's namespace handling, which the Enterprise build extends.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.