HashiCorp Certified: Vault Operations Professional 2022
Configure Access Control
Understanding Sentinel Policies
Sentinel is HashiCorp’s embedded policy-as-code framework, built directly into the Vault binary. It provides fine-grained, logic-based policy evaluation to permit or deny access to Vault paths and secrets based on dynamic conditions and external data.
With Sentinel you can:
- Treat policies like application code (version control, PR reviews, automated testing, CI/CD)
- Define condition-based rules (time, IP address, request path, MFA status, etc.)
- Pull in external data (current time, client IPs, request details)
- Enforce policies at three levels: advisory, soft mandatory, and hard mandatory
- Reuse the same policies across Terraform, Nomad, Vault, and Consul (enterprise editions)
Note
Sentinel is embedded in the Vault binary. No additional services or agents are required.
Sentinel Across HashiCorp Enterprise Products
Sentinel isn’t limited to Vault. It’s part of HashiCorp’s enterprise offerings for:
- Terraform
- Nomad
- Vault
- Consul
Once you author a Sentinel policy, you can apply it across these platforms with minimal changes.
Types of Sentinel Policies
Vault supports two main policy types:
Policy Type | Scope | Purpose |
---|---|---|
Role Governing Policy (RGP) | Tokens, identity entities, and groups | Govern actions identities can perform based on role logic |
Endpoint Governing Policy (EGP) | Specific API paths (authenticated or not) | Enforce conditions (source IP, business hours, MFA) per endpoint |
Example: An EGP on /dev/data
could deny all access outside business hours, regardless of token validity.
Anatomy of a Sentinel Policy
Every Sentinel policy consists of:
- Imports: Standard libraries—
base64
,decimal
,http
,json
,sockaddr
,time
,mfa
, etc. - Variables & helper rules: Reusable rule definitions.
- main rule: The required entry point. Returns
true
to allow orfalse
to deny.
Basic template:
import "<library>"
helper_rule = rule {
<condition>
}
main = rule {
<condition>
}
Common Sentinel Imports
base64
– Encode/decode Base64 stringsdecimal
– High-precision decimal arithmetichttp
– Perform HTTP requests within policiesjson
– Parse and manipulate JSON datasockaddr
– Handle IP addresses and CIDR blockstime
– Load, compare, and parse timestampsmfa
– Access the results of MFA methodsstrings
– String manipulation functions
Example RGP: Allow Specific Identities
This RGP grants access only to identities named “jeff” or members of the “sysops” group:
main = rule {
identity.entity.name is "jeff" or
identity.entity.id is "fe2a5bfd-c483-9263-b0d4-f9d345efdf9f" or
"sysops" in identity.groups.names or
"14c0940a-5c07-4b97-81ec-0d423accb8e0" in keys(identity.groups.by-id)
}
Using the entity ID prevents bypass by deleting and recreating the user.
Example EGP 1: Revoke Old Tokens
Apply to all paths (*
) to deny tokens issued before a cutoff timestamp:
import "time"
main = rule when not request.unauthenticated {
time.parse(request.auth.token.creation_time).unix >
time.parse("2022-12-25T00:00:01Z").unix
}
when not request.unauthenticated
ensures this only applies to authenticated requests.- Denies any token created before December 25, 2022.
Example EGP 2: LDAP Login with MFA and IP Check
This policy requires both an IP CIDR check and a Ping MFA challenge on auth/ldap/login
:
import "sockaddr"
import "mfa"
# IP must be within 10.0.23.0/16
cidrcheck = rule {
sockaddr.is_contained(request.connection.remote_addr, "10.0.23.0/16")
}
# Require Ping MFA validation
ping_valid = rule {
mfa.methods.ping.valid
}
main = rule when request.path is "auth/ldap/login" {
ping_valid and cidrcheck
}
Enforcement Levels
When creating RGPs or EGPs you choose:
- Advisory: Failures are logged but do not block requests.
- Soft Mandatory: Failures block requests unless
?policy_override=true
is specified. - Hard Mandatory: Failures block requests with no override allowed.
Creating Sentinel Policies in the Vault UI
Role Governing Policy (RGP)
- Navigate to Policies > Role Governing
- Click Create Policy
- Enter a name (e.g.,
business-hours-access
) - Paste your Sentinel code:
import "time" # Weekdays (Mon–Fri) and 08:00–18:00 workdays = rule { time.now.weekday > 0 && time.now.weekday < 6 } workhours = rule { time.now.hour >= 8 && time.now.hour < 18 } main = rule { workdays and workhours }
- Select an enforcement level
- Click Create Policy
Endpoint Governing Policy (EGP)
- Go to Policies > Endpoint Governing
- Click Create Policy
- Provide a name (e.g.,
cidr-validation-jenkins
) - Paste the policy:
import "sockaddr" cidrcheck = rule { sockaddr.is_contained(request.connection.remote_addr, "10.0.16.88/32") } main = rule { cidrcheck }
- Add the target paths (e.g.,
kv/automation/jenkins
) - Choose enforcement level
- Click Create Policy
Policy Evaluation Flow
- Unauthenticated path?
- Yes → Evaluate any EGP on that path and permit/deny immediately.
- Authenticated request
a. Evaluate Vault ACL policies attached to the token; deny on failure.
b. Evaluate RGPs attached to the identity; deny on failure.
c. Evaluate any EGP on the requested path; deny on failure.
d. If all checks pass → Access Permitted
Performance Warning
Adding multiple Sentinel policies can increase evaluation overhead and may impact latency under heavy request loads. Monitor performance and optimize your rules accordingly.
Root Token Bypass
Root tokens automatically bypass all Sentinel evaluations and are always granted access. For realistic performance testing, use regular service or batch tokens instead of root.
References
- Vault Sentinel Documentation
- HashiCorp Enterprise Sentinel
- Vault Policy Management
- Terraform Enterprise Sentinel
Watch Video
Watch video content