.
Sentinel
A language and framework for policy decisions across HashiCorp products
🚀 Introduction
Sentinel is a language and framework for policy built to be embedded in existing software to enable fine-grained, logic-based policy decisions. A policy describes under what circumstances certain behaviors are allowed.
Sentinel is an enterprise-only feature of HashiCorp Consul, Nomad, Terraform, and Vault, helping organizations enforce consistent governance across their infrastructure.
🛠️ Provision
Choose one of the following methods to set up your environment:
vagrant up --provision-with basetools,docsify,sentinel
docker compose exec hashiqube /bin/bash
bash hashiqube/basetools.sh
bash docker/docker.sh
bash docsify/docsify.sh
bash sentinel/sentinel.sh
📝 Basic Policy Example
Once installed, you can see Sentinel in action with a simple policy example. Here's a basic policy that checks if the current hour is in the morning (between 0 and 12):
hour = 4
main = rule { hour >= 0 and hour < 12 }
This policy is saved to /tmp/policy.sentinel
and then applied using:
sentinel apply /tmp/policy.sentinel
Output:
Pass
🔍 Advanced Sentinel Policies
Sentinel can handle complex policy scenarios. Let's explore more advanced examples from the HashiCorp TFE Policies Example repository.
AWS Block Allow All CIDR
This policy prevents security groups from using overly permissive CIDR blocks.
Testing the Policy
sentinel test aws-block-allow-all-cidr.sentinel
Output:
PASS - aws-block-allow-all-cidr.sentinel
PASS - test/aws-block-allow-all-cidr/empty.json
PASS - test/aws-block-allow-all-cidr/fail.json
PASS - test/aws-block-allow-all-cidr/pass.json
ERROR - test/aws-block-allow-all-cidr/plan.json
Applying the Policy
With a passing configuration:
sentinel apply -config ./test/aws-block-allow-all-cidr/pass.json aws-block-allow-all-cidr.sentinel
Output:
Pass
With a failing configuration:
sentinel apply -config ./test/aws-block-allow-all-cidr/fail.json aws-block-allow-all-cidr.sentinel
Output:
Fail
Execution trace. The information below will show the values of all
the rules evaluated and their intermediate boolean expressions. Note that
some boolean expressions may be missing if short-circuit logic was taken.
FALSE - aws-block-allow-all-cidr.sentinel:69:1 - Rule "main"
TRUE - aws-block-allow-all-cidr.sentinel:70:2 - ingress_cidr_blocks
TRUE - aws-block-allow-all-cidr.sentinel:50:2 - all get_resources("aws_security_group") as sg {
all sg.applied.ingress as ingress {
all disallowed_cidr_blocks as block {
ingress.cidr_blocks not contains block
}
}
}
FALSE - aws-block-allow-all-cidr.sentinel:71:2 - egress_cidr_blocks
FALSE - aws-block-allow-all-cidr.sentinel:60:2 - all get_resources("aws_security_group") as sg {
all sg.applied.egress as egress {
all disallowed_cidr_blocks as block {
egress.cidr_blocks not contains block
}
}
}
FALSE - aws-block-allow-all-cidr.sentinel:59:1 - Rule "egress_cidr_blocks"
TRUE - aws-block-allow-all-cidr.sentinel:49:1 - Rule "ingress_cidr_blocks"
AWS ALB Redirect
This policy ensures that AWS Application Load Balancer listeners use proper redirect status codes.
Testing the Policy
sentinel test aws-alb-redirect.sentinel
Output:
PASS - aws-alb-redirect.sentinel
PASS - test/aws-alb-redirect/empty.json
PASS - test/aws-alb-redirect/fail.json
PASS - test/aws-alb-redirect/pass.json
ERROR - test/aws-alb-redirect/plan.json
Applying the Policy
With a failing configuration:
sentinel apply -config ./test/aws-alb-redirect/fail.json aws-alb-redirect.sentinel
Output:
Fail
Execution trace. The information below will show the values of all
the rules evaluated and their intermediate boolean expressions. Note that
some boolean expressions may be missing if short-circuit logic was taken.
FALSE - aws-alb-redirect.sentinel:69:1 - Rule "main"
FALSE - aws-alb-redirect.sentinel:70:2 - default_action
FALSE - aws-alb-redirect.sentinel:49:2 - all get_resources("aws_lb_listener") as ln {
all ln.applied.default_action as action {
all action.redirect as rdir {
rdir.status_code == redirect_status_code
}
}
}
FALSE - aws-alb-redirect.sentinel:48:1 - Rule "default_action"
With a passing configuration:
sentinel apply -config ./test/aws-alb-redirect/pass.json aws-alb-redirect.sentinel
Output:
Pass
💡 Common Use Cases
Sentinel policies can be used to enforce a wide variety of governance requirements:
- Security: Ensure resources follow security best practices
- Compliance: Enforce regulatory requirements across infrastructure
- Cost Management: Prevent deployment of expensive resources
- Standardization: Maintain consistent naming and tagging conventions
- Architecture: Enforce architectural standards like network configuration
📚 Resources
- Sentinel Documentation
- Sentinel Language Guide
- Example Policies Repository
- Terraform Cloud Sentinel Examples
- Sentinel Playground
#!/bin/bash
function sentinel-install() {
arch=$(lscpu | grep "Architecture" | awk '{print $NF}')
if [[ $arch == x86_64* ]]; then
ARCH="amd64"
elif [[ $arch == aarch64 ]]; then
ARCH="arm64"
fi
echo -e '\e[38;5;198m'"CPU is $ARCH"
sudo DEBIAN_FRONTEND=noninteractive apt-get --assume-yes install -qq curl unzip jq < /dev/null > /dev/null
if [ -f /usr/local/bin/sentinel ]; then
echo -e '\e[38;5;198m'"++++ `/usr/local/bin/sentinel version` already installed at /usr/local/bin/sentinel"
else
LATEST_URL=$(curl --silent https://releases.hashicorp.com/index.json | jq '{sentinel}' | egrep "linux.*$ARCH" | sort -rh | head -1 | awk -F[\"] '{print $4}')
wget -q $LATEST_URL -O /tmp/sentinel.zip
mkdir -p /usr/local/bin
(cd /usr/local/bin && unzip /tmp/sentinel.zip)
echo -e '\e[38;5;198m'"++++ Installed: `/usr/local/bin/sentinel version`"
fi
# add basic configuration settings for Vault to /etc/vault/config.hcl file
cat <<EOF | sudo tee /tmp/policy.sentinel
hour = 4
main = rule { hour >= 0 and hour < 12 }
EOF
echo -e '\e[38;5;198m'"++++ cat /tmp/policy.sentinel"
cat /tmp/policy.sentinel
echo -e '\e[38;5;198m'"++++ sentinel apply /tmp/policy.sentinel"
sentinel apply /tmp/policy.sentinel
echo -e '\e[38;5;198m'"++++ Let's test some more advanced Sentinel Policies"
# https://github.com/hashicorp/tfe-policies-example
# https://docs.hashicorp.com/sentinel/language/
echo -e '\e[38;5;198m'"++++ https://github.com/hashicorp/tfe-policies-example"
echo -e '\e[38;5;198m'"++++ https://docs.hashicorp.com/sentinel/language/"
cd /vagrant/sentinel/sentinel/
echo -e '\e[38;5;198m'"++++ sentinel test aws-block-allow-all-cidr.sentinel"
sentinel test aws-block-allow-all-cidr.sentinel || true
echo -e '\e[38;5;198m'"++++ sentinel apply -config ./test/aws-block-allow-all-cidr/pass.json aws-block-allow-all-cidr.sentinel"
sentinel apply -config ./test/aws-block-allow-all-cidr/pass.json aws-block-allow-all-cidr.sentinel
echo -e '\e[38;5;198m'"++++ sentinel apply -config ./test/aws-block-allow-all-cidr/fail.json aws-block-allow-all-cidr.sentinel"
sentinel apply -config ./test/aws-block-allow-all-cidr/fail.json aws-block-allow-all-cidr.sentinel || true
echo -e '\e[38;5;198m'"++++ sentinel test aws-alb-redirect.sentinel"
sentinel test aws-alb-redirect.sentinel || true
echo -e '\e[38;5;198m'"++++ sentinel apply -config ./test/aws-alb-redirect/fail.json aws-alb-redirect.sentinel"
sentinel apply -config ./test/aws-alb-redirect/fail.json aws-alb-redirect.sentinel || true
echo -e '\e[38;5;198m'"++++ sentinel apply -config ./test/aws-alb-redirect/pass.json aws-alb-redirect.sentinel"
sentinel apply -config ./test/aws-alb-redirect/pass.json aws-alb-redirect.sentinel
}
sentinel-install