Sentinel policies are written using the Sentinel language. This languageis easy to learn and easy to write. You can learn the Sentinel languageand be productive within an hour. Learning Sentinel doesn't require anyformal programming experience.
This language guide will contain many details that are not necessary tobe productive with Sentinel or are targeted to those who are looking forexact information about the language (such as what types of line endings areallowed). You can safely ignore these sentences.
You may also view theofficial language specificationThis is a specific and detailed document on the syntax and behavior ofthe language primarily intended for implementation creators and to disambiguatethe language.
The example below is about the simplest practical example of Sentinel.It is reasonable to imagine this as a realistic policy. This shows thatin most cases, Sentinel will be extremely simple:
main = rule { request.method is "GET" and request.headers contains "X-Key" }
Files
Sentinel policies are single files that end in the .sentinel
file extension.There is currently no built-in mechanism to Sentinel for merging multiplefiles. This is purposefully done to make Sentinel policies easy to submitto systems that support Sentinel policies.
Sentinel policy files must be UTF-8 encoded and can end in bothUnix (LF) or Windows (CRLF) line breaks. When running theauto-formatter,line endings will always use Unix line breaks.
Sentinel policies are executed top-down. For example:
a = 1 // a = 1 hereb = a + 1 // b = 2 herea = 3 // a = 3, b = 2
In this example, the value of a
and b
is shown at each line. Since Sentinelexecutes values top-down, the final value of a
is 3 and b
is 2. b
doesnot become 4.
Main
Sentinel expects there to be a main
rule.The value of this rule is the result of the entire policy.
The result of the policy depends on the evaluated contents of the main
rule.For booleans, a policy passes on a true
value, and fails on a false
value.Other types generally follow a zero or zero-length pattern for determiningsuccess.
Type | Passing Condition | Failing Condition |
---|---|---|
Boolean | true | false |
String | "" | Any non-zero length string |
Integer | 0 | Any non-zero value |
Float | 0.0 | Any non-zero value |
List | [] | Any non-zero length list |
Map | {} | Any non-zero length map |
A value of main that falls outside of the above types will result in a policyerror. As a special case, if main
evaluates to an undefined value, the errormessage will indicate as such, with a reference to where the undefined value wasencountered.
The simple example above is a full working example. In our experience withSentinel, many policies can be representing using this simple form. However,to show more features of the language, a more complex example is shown below.This example is also a realistic example of what Sentinel may be used for.
import "units"memory = func(job) { result = 0 for job.groups as g { for g.tasks as t { result += t.resources.memory else 0 } } return result}main = rule { memory(job) < 1 * units.gigabyte}