Skip to main content

Watch an Introduction to Sentinel with Armon Dadgar


Policy as code framework for HashiCorp Enterprise Products.

What is Sentinel

Sentinel is an embeddable policy as code framework to enable fine-grained, logic-based policy decisions that can be extended to source external information to make decisions.

Sentinel across our Product Suite

How Sentinel integrates into HashiCorp Enterprise Products

Policy as Code in Terraform Enterprise

  • Policies are enforced in Terraform Enterprise between the plan and apply.
  • Policies validate information in the Terraform plan, state, and configuration.
  • Do not allow resources to be provisioned without tags
  • Only provision staging resources in us-west and production resources in us-east
  • Do not allow AWS security groups to have egress set to
Code Sample
import "tfplan/v2" as tfplan
aws_instances = filter tfplan.resource_changes as _, rc {
	rc.mode is "managed" and
		rc.type is "aws_instance" and
		rc.change.actions is not "delete"
main = rule {
	all aws_instances as _, instance {
		(instance.change.after.tags else {}) is not empty

Policy as Code in Vault Enterprise

  • Policies are enforced in front of all Vault APIs.
  • Policies extend Vault's ACL system with fine-grained logic.
  • Ensure that modification of critical data can only be performed by authorized sysops with valid MFA
  • Require LDAP logins to come from internal IP space and successfully pass a Ping MFA check
  • Applied to all endpoints in response to a breach, ensure that any token generated more than four hours ago cannot be used
Code Sample
import "strings"
// Scope this policy only to operations that change data within our dangerous
// area
pathcheck = rule {
    strings.has_prefix(request.path, "secret/dangerous/") and
        request.operation in ["create", "update", "delete"]
// Ensure that for this dangerous operation we've passed an Okta MFA check
oktacheck = rule {
// Make sure the caller is a member of the sysops group
idcheck = rule {
    "sysops" in identity.groups
main = rule when pathcheck {
    oktacheck and idcheck

Policy as Code in Nomad Enterprise

  • Policies are enforced before accepting new jobs or updating existing jobs.
  • Policies extend Nomad's ACL system with fine-grained logic.
  • Policies can enforce only trusted artifacts or applications are allowed to run.
  • Only allow Docker workloads
  • Limit jobs to only 5 GB of memory resources
Code Sample
allowed_drivers = ["docker"]
main = rule {
    all job.task_groups as tg {
        all tg.tasks as t { t.driver in allowed_drivers }

Policy as Code in Consul Enterprise

  • Policies are enforced in front Consul's K/V and services APIs.
  • Policies extend Consul's ACL system with fine-grained logic.
  • Key/value must be in proper format (such as integer, text, etc.).
  • Consul keys can only be updated during business hours
Code Sample
required = [
  ["port", "\\d+"], // port must be int
  ["name", "\\w+"], // name must be one or more words
valid_key = func() {
  for required as v {
    if request.kv.key is v[0] {
      return request.kv.value matches v[1]
  // Unknown key
  return false
is_kv_request = rule {
  request.path matches "^/kv" and
  request.method is "PUT"
main = rule when is_kv_request { valid_key() }

Policy as code is the next phase of infrastructure automation

Infrastructure as Code was the first phase, which enables codification and automation for the four main components of infrastructure — provision, secure, connect, and run. Infrastructure as Code empowers more users to create and manage infrastructure; however, that comes with risks as less experienced users could make significant mistakes that impact business operations.

Policy as code limits exposure by codifying business and regulatory policies to ensure infrastructure changes are safe. Together Infrastructure as Code and Policy as code empower users to safely and quickly provision, secure, connect, and run any infrastructure for any application.

Ready to get started?

Get in touch or start exploring the documentation.