
This Article only discusses about following topics in Sentinel Language:
- Rules
- Imports
- Parameters
Sentinel policies are written using the Sentinel language. This language is easy to learn and easy to write. You can learn the Sentinel language and be productive within an hour. Learning Sentinel doesn’t require any formal programming experience.
Language: Rules
Rules form the basis of a policy by representing behavior that is either passing or failing. A policy can be broken down into a set of rules. Breaking down a policy into a set of rules can make it more understandable and aids with testing.
An example is shown below:
weather = "sunny"
day = "wednesday"
is_sunny = rule { weather is "sunny" }
is_wednesday = rule { day is "wednesday" }
main = rule {
is_sunny and
is_wednesday
}
Output:
Sentinel Result: true
This result means that all Sentinel policies passed and the protected
behavior is allowed.
1 policies evaluated.
## Policy 1: policy.sentinel (hard-mandatory)
Result: true
policy.sentinel:6:1 - Rule "main"
Value:
true
policy.sentinel:3:1 - Rule "is_sunny"
Value:
true
policy.sentinel:4:1 - Rule "is_wednesday"
Value:
true
A rule contains a single expression. This can be a simple boolean expression, or an expression representing the discovery of a set of violations using more in-depth expressions like filter
and map
. You can split expressions into multiple lines for readability, as you would with any other expression within Sentinel.
A rule is also lazy and memoized. Lazy means that the rule is only evaluated when it is actually required, not at the point that it is created. Memoized means that the value is only computed once and then saved. Once a rule is evaluated, the result of it is reused anytime the rule is referenced again.
Easing Understandability
Rules are an abstraction that make policies much more understandable by making it easier for humans to see what the policy is trying to do.
For example, consider the policy before which doesn’t abstract into rules:
main = rule {
((day is "saturday" or day is "sunday") and homework is "") or
(day in ["monday", "tuesday", "wednesday", "thursday", "friday"] and
not school_today and homework is "")
}
Assume that day
, homework
, and school_day
are available.
In plain English, this policy is trying to say: you can play with your friends only on the weekend as long as there is no homework, or during the week if there is no school and no homework.
Despite the relatively simple nature of this policy (a few lines, about 5 logical expressions), it is difficult to read and understand, especially if you’ve not seen it before.
The same policy using rules as an abstraction:
is_weekend = rule { day in ["saturday", "sunday"] }
is_valid_weekend = rule { is_weekend and homework is "" }
is_valid_weekday = rule { not is_weekend and not school_today and homework is "" }
main = rule { is_valid_weekend or is_valid_weekday }
By reading the names of the rules, its much clearer to see what each individual part of the policy is trying to achieve. The readability is improved even further when adding comments to the rules to explain them further, which is a recommended practice:
// A weekend is Sat or Sun
is_weekend = rule { day in ["saturday", "sunday"] }
// A valid weekend is a weekend without homework
is_valid_weekend = rule { is_weekend and homework is "" }
// A valid weekday is a weekday without school
is_valid_weekday = rule { not is_weekend and not school_today and homework is "" }
main = rule { is_valid_weekend or is_valid_weekday }
“When” Predicates
A rule may have an optional when
predicate attached to it. When this is present, the rule is only evaluated when the predicate results in true
. Otherwise, the rule is not evaluated and the result of the rule is always true
.
“When” predicates should be used to define the context in which the rule is semantically meaningful. It is common when translating human language policy into Sentinel to have scenarios such as “when the key has a prefix of /account/
, the remainder must be numeric.” In that example, when the key does not have the specified prefix, the policy doesn’t apply.
Assume you have rules is_prefix
and is_numeric
to check both the conditions in the example above. An example is shown with and without the “when” predicate:
example_no_when = rule { (is_prefix and is_numeric) or not is_prefix }
example_when = rule when is_prefix { is_numeric }
The rules are equivalent in behavior for all values of is_prefix
and is_numeric
, but the second rule is more succint and easier to understand.
Testing
To verify a policy works correct, the built-in Sentinel test framework uses rules as the point where you can assert behavior. You say that you expect certain rules to be true or false. By doing so, you ensure that the policy results in the value you expect using the rule flow that you expect.
Therefore, in addition to readability, we recommend splitting policies into rules to aid testability.
Non-Boolean Values
Sentinel supports non-boolean values in rules. This can be useful for passing more detail along to a calling integration when more detail is required than a boolean value would be able to communicate. This data shows up in the policy trace and can be utilized in different ways depending on the integration you are using Sentinel with.
Consider a different take on our policy above:
// A policy to check a set of scheduled days to determine what days you can't
// come out and play, based on the day not being a weekend day and there being
// homework to do.
param days
main = rule {
filter days as d {
d.day not in ["saturday", "sunday"] and
d.homework is not ""
}
}
When given a value in the set of days
that has a day
that is a weekday, and homework
present, the policy will fail. Additional, when tracing was enabled, the days that were detected as violating the policy would be given in the trace for the main
rule.
Generally, for non-boolean values, a policy fails on non-zero data. See the details on the main
rule for more details.
The result of a rule must be either a boolean, string, integer, float, list, or map. All other types will result in a runtime error.
Lazy and Memoized
A rule is lazy and memoized.
Lazy means that the rule is only evaluated when it is actually required, not at the point that it is created. And memoized means that the value is only computed once and then saved. Once a rule is evaluated, the result of it is reused anytime the rule is referenced again.
Both of these properties have important implications for Sentinel policies:
Performance: Rules are a way to improve the performance of a Sentinel policy. If you have a boolean expression that is reused a lot, a rule will only be evaluated once. In the example shown above, is_weekend
is used multiple times, but will only have to be evaluated once.
Behavior: Rules accessing variables see the value of those variables at the time they are evaluated. This can lead to surprising behavior in some cases. For example:
a = 1
b = rule { a == 1 }
a = 2
main = b
In this example, main
will actually result to false
. It is evaluated when it is needed, which is when the policy executes main
. At this point, a
is now 2 and b
has not been evaluated yet. Therefore, b
becomes false
. All future references to b
will return false
since a rule is memoized.
Language: Imports
Imports enable a Sentinel policy to access reusable libraries and external data and functions. The exact list of available imports is dependent on the host system. Host systems may also make the available imports configurable via plugins.
Imports are extremely powerful. They enable policy decision based on arbitrary external information. For example, a behavior coming into a system can be allowed or denied based on information from a separate system where the two systems can be unaware of each other.
The example below shows a concrete example. For the example, imagine that the import calendar
allows access to engineer calendars. This import only exists for the purpose of this example and at the time of writing is not a real available import.
import "calendar"
// Get the calendar for Bob for today
bob_calendar = calendar.for("bob").today
// Allow this policy to pass if Bob is not on vacation.
main = rule { not bob_calendar.has_event("vacation") }
This example shows an import being used to deny a behavior if Bob is on vacation. Hopefully real policies do not depend on a single person being in the office, but the example shows the power of imports.
In addition to consuming imports, you can also extend Sentinel by writing custom imports This allows you to add any arbitrary behavior to your Sentinel-protected systems
Importing
Whether accessing a built-in library or an external plugin, the syntax for an import is the same:
import "name"
This adds the import with the name name
. It can be referenced using the identifier name
. For example, if the import above exposed first and last name data, you could access it via name.first
or name.last
.
You can shadow imports by assigning a variable. In the example below, the import name
becomes unavailable within the function because it is shadowed by a variable of the same name.
Shadowing an import is not the same as overwriting a variable. Imports are not part of the scope, meaning that the shadow only exists for the scope it is created within. For everything else, the import works even after it is shadowed. The example below shows that as well.
import "name"
f = func() {
name = "jane"
return name
}
print(f()) // "jane"
print(name.first) // "bob"
Aliases
An import can be aliased to another name using the syntax below:
import "name" as other
This would make the import “name” available as other
.
An import may only be imported once, regardless of aliases. The following would be invalid and would result in an error:
import "name" as one
import "name" as two
Imports are accessed with dot-separated identifiers, such as name.first
or name.stage.first
. These are called selector expressions. An import may return nested data that further can be accessed via selector expressions.
In the first example on this page with the “calendar” import, we see this:
import "calendar"
a = calendar.for("bob") // selector expression calendar.for
b = a.today // selector expression on the result
c = b.vacation // accessing further nested data
The exact structure of an import is dependent on the import. Please reference the documentation for an import to learn more.
Language: Parameters
Sentinel allows a policy author to supply parameters to help facilitate policy reuse and ensure sensitive values do not need to be hard-coded in a policy.
Parameters are supplied by using the param
keyword, followed by an identifier. A default value can also be supplied by using the default
keyword.
param foo // assigned to foo, required
param bar default 42 // assigned to bar, optional, default 42
Once declared, parameters can be used like any other variable, including being re-assigned.
param foo default 1 // 1 (default)
foo = foo + 1 // 2
Variable Descriptions
You can supply a description to a parameter by adding a comment at the top of it. This value can be communicated to a specific implementation of Sentinel to provide information about what the parameter is for during configuration.
// An example parameter. Must be supplied or the policy will fail.
param foo
Supplying Parameter Values Using the Sentinel CLI
In a production implementation, supplying parameters to a policy is an implementation-specific detail – see the documentation for your particular implementation for details.
Using the Sentinel CLI, you can supply parameters one of four ways.
1. Supplying Parameter Values Using the Configuration File
You can supply parameters using the param
section of the configuration file.
{
"param": {
"foo": "bar"
}
}
This method works for both sentinel apply
and sentinel test
.
2. Supplying Parameter Values Using the Environment
NOTE: This method of supplying parameters is only supported by sentinel apply
.
You can supply a value using environment variables – prefix the parameter with SENTINEL_PARAM_
, using the name of the parameter to supply.
SENTINEL_PARAM_foo=bar sentinel apply policy.sentinel
3. Supplying Parameter Values Using the CLI
NOTE: This method of supplying parameters is only supported by sentinel apply
.
You can also use the -param
CLI argument to supply parameter in a key=value
pair.
sentinel apply -param foo=bar policy.sentinel
4. Interactive CLI Prompting
NOTE: This method of supplying parameters is only supported by sentinel apply
.
If a required value has not been supplied when a policy is run with sentinel apply
, it will be prompted for, along with its description:

CLI Value Format
NOTE: This section contains details for the parameter features supported by sentinel apply
.
The CLI takes either strings, or JSON numbers, arrays, or maps. If you need a literal string value, quote the value.
foo // string
42 // number (float)
"42" // string ("42", without quotes)
[1, 2] // array (list)
{"a": "b"} // object (map)
NOTE: Boolean values are not supported by this method.
Your article helped me a lot, is there any more related content? Thanks! https://accounts.binance.com/fr/register-person?ref=P9L9FQKY
The point of view of your article has taught me a lot, and I already know how to improve the paper on gate.oi, thank you.
I agree with your point of view, your article has given me a lot of help and benefited me a lot. Thanks. Hope you continue to write such excellent articles.
Hello! I’m at work surfing around your blog from my new iphone 3gs!
Just wanted to say I love reading your blog and look forward to all your posts!
Keep up the outstanding work!
My web-site; oil pulling teeth whitening
I’m extremely inspired with your writing abilities as well as with the
format on your blog. Is this a paid theme or did you customize it your self?
Either way stay up the excellent high quality writing, it’s rare to see a great weblog like this one nowadays..
My web-site … Horacio
You made some respectable factors there. I looked on the innternet for the problm and
located most individuals will go along with together with your website.
Thanks for sharing your thoughts on seeds require. Regards
Also visit my blog post; prettypeople.club
Highly energetic blog, I liked that bit. Will there be a part 2?
Also visit my web site healthy weight
My family always say that I am wasting my time here at web,
except I know I am getting knowledge everyday by reading such nice articles or reviews.
Here is my blog post … effective skin care
Very interesting details you have remarked, regards for posting.
Visit my web-site skin type
I believe you have remarked some very interesting details, appreciate it for the post.
Feel free to surf to my blog :: moonlightmining.com
Just desire to say your article is as astounding. The clarity in your post is just nice and i could assume you’re an expert
on this subject. Fine with your permission allow me to grab your feed to keep updated
with forthcoming post. Thanks a million and please keep up the
enjoyable work.
Feel free to visit my web blog … natural skin
I really love your website.. Very nice colors & theme.
Did you build this amazing site yourself? Please reply back as
I’m wanting to create my own personal blog and want to know where you got this from or exactly what the theme is called.
Thank you!
Hello.This article was extremely remarkable, especially since I was looking for thoughts on this topic last Tuesday.
Also visit my homepage – calories eating
Incredible! This blog looks exactly like my old one!
It’s on a entirely different subject but it
has pretty much the same layout and design. Outstanding choice
of colors!
My page :: eating habits
What’s up to every body, it’s my first visit of this webpage; this weblog contains amazing and genuinely good material in favor of readers.
My homepage :: http://www.meteoritegarden.com
Very interesting information!Perfect just what I
was looking for!
Here is my webpage http://www.meteoritegarden.com
Thanks for the auspicious writeup. It in truth was a
enjoyment account it. Look advanced to more added agreeable from you!
However, how can we communicate?
Here is my webpage; calorie shifting diet
I seriously love your website.. Excellent colors & theme.
Did you build this website yourself? Please reply back as I’m wanting to
create my very own blog and want to learn where you got this from or just what the theme is called.
Thank you!
Can you tell us more about this? I’d want to find out more details.
What a data of un-ambiguity and preserveness of valuable experience on the topic of unpredicted feelings.
My site: boost libido in men
Wonderful paintings! This is the type of information that
are meant to be shared around the web. Disgrace on the search engines for no longer positioning this
submit upper! Come on over and seek advice
from my web site . Thank you =)
my blog – Jefferson
Hey There. I found your blog using msn. This is a very well written article.
I will be sure to bookmark it and come back to read more of your useful info.
Thanks for the post. I will definitely return.
Magnificent web site. Lots of helpful info here. I am sending it to some
pals ans also sharing in delicious. And of course, thanks to your sweat!
My blog post; quality treatment
Great site. A lot of useful information here. I
am sending it to several buddies ans also sharing in delicious.
And certainly, thanks to your sweat!
Here is my page; term treatment process
Some truly fantastic blog posts on this
web site, thanks for contribution.
my web blog :: love life
Hey! Do you use Twitter? I’d like to follow you if that would be okay.
I’m absolutely enjoying your blog and look forward to new posts.
Pretty section of content. I just stumbled upon your website and in accession capital to assert that
I get actually enjoyed account your blog posts.
Anyway I will be subscribing to your feeds and even I achievement you access consistently quickly.
I was just looking for this info for some time.
After six hours of continuous Googleing, at last I got it in your website.
I wonder what’s the lack of Google strategy that don’t rank this kind
of informative web sites in top of the list. Usually the
top websites are full of garbage.
Feel free to surf to my homepage facial skin care tips
I feel that is among the so much significant info for me.
And i’m satisfied studying your article. But should observation on few basic issues, The website taste is great, the articles is actually excellent : D.
Good job, cheers
Hi there would you mind stating which blog platform you’re using?
I’m looking to start my own blog in the near future but I’m having a tough time selecting between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your design and style
seems different then most blogs and I’m looking for something
completely unique. P.S My apologies for getting off-topic but I had to ask!
Here is my web page: rapid muscle development
We stumbled over here from a different web address and thought I may as well check things
out. I like what I see so now i’m following you. Look forward to looking over your web page repeatedly.
Look at my website :: Annette
Yay google is my world beater aided me to find this great web site!
Also visit my web site: weight loss diet
I like the valuable info you provide in your
articles. I’ll bookmark your weblog and check again here frequently.
I am quite sure I’ll learn many new stuff right here!
Best of luck for the next!
Hi there, I read your new stuff regularly. Your story-telling style is awesome, keep up the good work!
Here is my homepage … atkins diet
Thank you for some other informative website. Where else could I am getting
that type of info written in such an ideal manner?
I have a challenge that I am just now running on, and I have been at the glance out for
such info.
Have a look at my web page: fast weight loss
Hello.This post was really motivating, particularly since I was browsing for thoughts on this subject
last Wednesday.
Feel free to surf to my homepage: prettypeople.club
Asking questions are genuinely good thing if you are not understanding something
completely, but this piece of writing gives good understanding yet.
my page – hair loss
Well I sincerely enjoyed studying it. This subject procured by you is very useful for correct
planning.
My web blog – moonlightmining.com
This site truly has all of the info I wanted concerning this subject and
didn?t know who to ask.
Review my blog: low carb eating
Great goods from you, man. I’ve be mindful your stuff prior to and
you are simply too excellent. I really like what you
have obtained here, certainly like what you’re stating and the
way in which during which you say it. You are making it enjoyable and you continue to take
care of to stay it wise. I cant wait to read much more from you.
That is actually a great website.
my web blog: eating low carb diet
I am glad to be a visitor of this everlasting weblog, thanks for
this rare information!
Have a look at my blog; testosterone booster