Sentinel
Write your first policy
With Sentinel installed, you are ready to create your first policy.
In this tutorial, you will write a Sentinel policy for HashiCups, a fictional coffee shop. This policy will validate coffee orders, ensuring they meet specific criterias. Sentinel policies let you enforce business rules to standardize your operations.
Prerequisites
To follow this tutorial, you need the Sentinel CLI installed locally on your machine.
Tip
You can find the complete configuration for these tutorials in the Learn Sentinel Get Started GitHub repository. The configuration for this specific tutorial is in the 01-write-policy
branch.
Create a directory for your Sentinel policies.
$ mkdir learn-sentinel-hashicups
Change into the directory.
$ cd learn-sentinel-hashicups
Set up the Sentinel file structure
Before writing your first policy, we recommend you set up the file structure for your Sentinel project. While you can format it in any way, the following structure helps organize your policies and makes it easier to manage as your project grows.
The recommended structure includes a Sentinel configuration file and a policies directory.
Create the Sentinel configuration file. Sentinel uses this file to determine how to load and apply your policies. You will add contents to this file later in this tutorial.
$ touch sentinel.hcl
Create a policies
directory to store your Sentinel policies.
$ mkdir policies
Your project structure should now look like the following.
learn-sentinel-hashicups/
├── sentinel.hcl
└── policies/
Write policy
HashiCups wants to ensure each coffee order is valid — the order should only contain valid coffee names and sizes.
Create a file for this policy.
$ touch policies/validate_coffee_order.sentinel
Open policies/validate_coffee_order.sentinel
in your text editor, paste in the configuration below, and save the file.
policies/validate_coffee_order.sentinel
# Parameters and variables
param coffee_name default "HCP Aeropress"
param coffee_size default "small"
# Valid coffee names
valid_coffees = [
"HCP Aeropress",
"Packer Spiced Latte",
"Vaulatte",
"Nomadicano",
"Terraspresso",
"Vagrante espresso",
"Connectaccino",
"Boundary Red Eye",
"Waypointiato",
]
valid_sizes = ["small", "medium", "large"]
## Rules
# Validate coffee name
validate_name = rule {
coffee_name in valid_coffees
}
# Validate coffee size
validate_size = rule {
coffee_size in valid_sizes
}
# Main rule to validate a coffee order
main = rule {
validate_name and
validate_size
}
This is a complete Sentinel policy that you can evaluate. The following sections review each block of this configuration in more detail.
Parameters and Variables
Sentinel uses both parameters and variables to store and reference data within your policy. While they may seem similar, they serve different purposes and have distinct characteristics.
Parameters
Parameters let you pass external values into a policy, making your policies more flexible and reusable.
This policy defines coffee_name
and coffee_size
as parameters with default values for a coffee order. You can override these defaults when you apply the policy, allowing you to test different scenarios without changing the policy code.
policies/validate_coffee_order.sentinel
param coffee_name default "HCP Aeropress"
param coffee_size default "small"
Variables
Sentinel uses variables to store and reference data within your policy. They can hold simple values, lists, or complex data structures. Variables are useful for internal data organization and constants, which helps improves the readability and maintainability of your policy.
This policy contains two variables.
- The
valid_coffees
list contains all available coffee names from the HashiCups menu. - The
order
list contains all available sizes.
policies/validate_coffee_order.sentinel
valid_coffees = [
"HCP Aeropress",
"Packer Spiced Latte",
"Vaulatte",
"Nomadicano",
"Terraspresso",
"Vagrante espresso",
"Connectaccino",
"Boundary Red Eye",
"Waypointiato",
]
valid_sizes = ["small", "medium", "large"]
Rules
Rules are the core of Sentinel policies. They define the conditions that must be true for a policy to pass. Rules can use logical operators to combine multiple conditions, rules and functions to perform more complex evaluations.
Sentinel returns the result of the main function. If a rule within the main rule fails, Sentinel will notify you that both the main rule and the sub-rule fails. If a function within the main rule fails, Sentinel will only notify you the main rule failed.
This policy contains three rules:
- The
validate_name
rule checks if the coffee name is in the list of valid coffees. - The
validate_size
rule ensures the size is one of the allowed values. - The
main
rule combines the results of validate_name and validate_size using the and operator.
policies/validate_coffee_order.sentinel
# Validate coffee name
validate_name = rule {
coffee_name in valid_coffees
}
# Validate coffee size
validate_size = rule {
coffee_size in valid_sizes
}
# Main rule to validate a coffee order
main = rule {
validate_name and
validate_size
}
Format the policy
Format your policy to ensure your configuration is readable. You must explicitly specify the file you want to format.
$ sentinel fmt policies/validate_coffee_order.sentinel
1 file(s) formatted.
Define Sentinel configuration file
The Sentinel configuration file, typically named sentinel.hcl
, is a crucial component in managing your Sentinel policies. You can manage all your policies from a single file, making it easier to organize and maintain your policy set. The configuration file also makes it easier to integrate Sentinel policy checks into your continuous integration and deployment pipelines.
Open sentinel.hcl
in your text editor, paste in the configuration below, and save the file.
sentinel.hcl
policy "validate_coffee_order" {
source = "./policies/validate_coffee_order.sentinel"
}
policy "validate_coffee_order_override" {
source = "./policies/validate_coffee_order.sentinel"
params = {
coffee_name = "Cappuccino"
coffee_size = "extra-large"
}
}
Each policy
block in the sentinel.hcl
file defines a policy that Sentinel should evaluate. You can have multiple policy blocks, allowing you to manage several policies in one configuration file.
The source
parameter specifies the location of the Sentinel policy file relative to the sentinel.hcl
file. In this example, ./policies/validate_coffee_order.sentinel
tells Sentinel to look for the policy file in the policies
subdirectory.
You can define multiple policy blocks with different parameters, allowing you to test various scenarios without modifying the policy file itself. For example, you can create different configuration files for different environments (e.g., development, staging, production) with appropriate parameter overrides.
This configuration defines two policy instances.
- The
validate_coffee_order
policy uses the default parameter values. - The
validate_coffee_order_override
policy overrides the default parameters with an invalid name and size.
Apply the policy
Apply your policy with the Sentinel CLI. Notice, the validate_coffee_order
passes and the validate_coffee_order_override
fails as expected.
$ sentinel apply
Execution trace. The information below will show the values of all
the rules evaluated. Note that some rules may be missing if
short-circuit logic was taken.
Note that for collection types and long strings, output may be
truncated; re-run "sentinel apply" with the -json flag to see the
full contents of these values.
The trace is displayed due to a failed policy.
Pass - validate_coffee_order.sentinel
Fail - validate_coffee_order_override.sentinel
Description:
Main rule to validate a coffee order
validate_coffee_order_override.sentinel:33:1 - Rule "main"
Description:
Main rule to validate a coffee order
Value:
false
validate_coffee_order_override.sentinel:23:1 - Rule "validate_name"
Description:
Validate coffee name
Value:
false
Notice when you applied your Sentinel policies, Sentinel automatically creates a .sentinel
directory. Sentinel creates this runtime directory to store manifest files to associate Sentinel policy components with their source file. For example, in the .sentinel/policies/manifest.json
, you will find the following.
Depending on where you source your policies and modules, we recommend you add the .sentinel
directory to your .gitignore
file. Sentinel will look for the policy in the dest
path. Since this path is unique to each user at runtime, Sentinel may return an error.
.sentinel/policies/manifest.json
{
"records": [
{
"key": "validate_coffee_order_override",
"source": "./policies/validate_coffee_order.sentinel",
"sourceSum": "",
"dest": "/Users/education/learn-sentinel-get-started/policies/validate_coffee_order.sentinel"
},
{
"key": "validate_coffee_order",
"source": "./policies/validate_coffee_order.sentinel",
"sourceSum": "",
"dest": "/Users/education/learn-sentinel-get-started/policies/validate_coffee_order.sentinel"
}
]
}
Apply specific policy
Alternatively, you can also apply a specific policy. Apply the validate_coffee_order.sentinel
policy.
$ sentinel apply policies/validate_coffee_order.sentinel
Pass - validate_coffee_order.sentinel
You can override the policy parameters in the CLI. Apply the policy with an invalid parameter. The policy should fail as expected.
$ sentinel apply -param coffee_name="Terraspresso" -param coffee_size="extra-large" policies/validate_coffee_order.sentinel
Execution trace. The information below will show the values of all
the rules evaluated. Note that some rules may be missing if
short-circuit logic was taken.
Note that for collection types and long strings, output may be
truncated; re-run "sentinel apply" with the -json flag to see the
full contents of these values.
The trace is displayed due to a failed policy.
Fail - validate_coffee_order.sentinel
Description:
Main rule to validate a coffee order
validate_coffee_order.sentinel:33:1 - Rule "main"
Description:
Main rule to validate a coffee order
Value:
false
validate_coffee_order.sentinel:23:1 - Rule "validate_name"
Description:
Validate coffee name
Value:
true
validate_coffee_order.sentinel:28:1 - Rule "validate_size"
Description:
Validate coffee size
Value:
false
The param
block in the policy block override the -param
flag. Sentinel will fail since the validate_coffee_order_override
policy has invalid values in the param
block.
$ sentinel apply -param coffee_name="Terraspresso" -param coffee_size="medium"
Update failing policy
Update the validate_coffee_order_override
policy in the Sentinel configuration file with valid parameters. The following is an example of a valid coffee name and size.
sentinel.hcl
policy "validate_coffee_order" {
source = "./policies/validate_coffee_order.sentinel"
}
policy "validate_coffee_order_override" {
source = "./policies/validate_coffee_order.sentinel"
params = {
coffee_name = "Terraspresso"
coffee_size = "medium"
}
}
Verify that the policies are valid by applying Sentinel.
$ sentinel apply
Pass - validate_coffee_order.sentinel
Pass - validate_coffee_order_override.sentinel
Next steps
Now that you have created your first Sentinel policy, continue to the next tutorial to learn how to simplify policy logic with Sentinel functions.
For more information on topics covered in this tutorial, refer to the following documentation: