Sentinel: Introduction to Sentinel Language – Part-2

Share At:

Remote working: HashiCorp Sentinel gets HCL-proficient, learns how to get  remote policies • DEVCLASS

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 memoizedLazy 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 dayhomework, 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.


Share At:
0 0 votes
Article Rating
Subscribe
Notify of
guest
39 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
oil pulling teeth whitening

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

Horacio
22 days ago

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

https://www.mc-complex.com/forums/tekkit/members/alana5543.1843/about

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.

prettypeople.club
22 days ago

Thanks for sharing your thoughts on seeds require. Regards

Also visit my blog post; prettypeople.club

healthy weight
22 days ago

Highly energetic blog, I liked that bit. Will there be a part 2?

Also visit my web site healthy weight

effective skin care
22 days ago

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

skin type
22 days ago

Very interesting details you have remarked, regards for posting.

Visit my web-site skin type

moonlightmining.com
22 days ago

I believe you have remarked some very interesting details, appreciate it for the post.

Feel free to surf to my blog :: moonlightmining.com

natural skin
22 days ago

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

Norris
22 days ago

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!

calories eating
22 days ago

Hello.This article was extremely remarkable, especially since I was looking for thoughts on this topic last Tuesday.

Also visit my homepage – calories eating

eating habits
22 days ago

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

www.meteoritegarden.com

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

www.meteoritegarden.com

Very interesting information!Perfect just what I
was looking for!

Here is my webpage http://www.meteoritegarden.com

calorie shifting diet
22 days ago

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

instagram takipçi satın al

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!

Damaris
22 days ago

Can you tell us more about this? I’d want to find out more details.

boost libido in men
22 days ago

What a data of un-ambiguity and preserveness of valuable experience on the topic of unpredicted feelings.

My site: boost libido in men

Jefferson
22 days ago

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

Ali
Ali
22 days ago

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.

quality treatment
22 days ago

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

term treatment process

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

love life
22 days ago

Some truly fantastic blog posts on this
web site, thanks for contribution.

my web blog :: love life

Arnulfo
22 days ago

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.

Laura
22 days ago

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.

facial skin care tips
22 days ago

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

Monty
22 days ago

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

rapid muscle development

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

Annette
22 days ago

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

weight loss diet
22 days ago

Yay google is my world beater aided me to find this great web site!

Also visit my web site: weight loss diet

Angelia
22 days ago

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!

atkins diet
22 days ago

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

fast weight loss
22 days ago

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

prettypeople.club
22 days ago

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

hair loss
22 days ago

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

moonlightmining.com
22 days ago

Well I sincerely enjoyed studying it. This subject procured by you is very useful for correct
planning.

My web blog – moonlightmining.com

low carb eating
22 days ago

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

eating low carb diet
22 days ago

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

testosterone booster
25 days ago

I am glad to be a visitor of this everlasting weblog, thanks for
this rare information!

Have a look at my blog; testosterone booster

Back To Top

Contact Us