Rego Examples II
Overview
We will walkthrough following rego examples.
- User-Defined Function
- Built-in Function
- Negation
The built-in functions for the language provide basic operations to manipulate scalar values (e.g. numbers and strings), and aggregate functions that summarize complex types.
Rego supports user-defined functions that can be called with the same semantics as Built-in Functions. They have access to both the the data Document and the input Document.
Function Example
This rule checks if the input url matches the required pattern.
package policy.role
import future.keywords.ifallow := myresult if {
#url patterns
myUrls := ["example.com/?","example.com/??"]
inAllowedList(myUrls)
myresult := "tested successfully"
}# user-defined function
inAllowedList(myUrls):=true if{
#built-in function
(glob.match(myUrls[i], [], input.mysite.path))
}
Input
{
"mysite":
{"path": "example.com/ad"}
}
Output
[
{
"allow": "tested successfully"
}
]
I will test the policy rules from Styra DAS. You may get Styra DAS for training from Styra Academy.
Click “preview” to query the document.
Input:
{
“mysite”:
{“path”: “example.com/abc”}
}
Output: undefined
The policy still works with following syntax,
- Omit if
- Use equal sign instead of assignment (:=) in rule head (allow = myresult)
allow = myresult {
myUrls := ["example.com/?","example.com/??"]
inAllowedList(myUrls)
myresult := "tested successfully"
}
inAllowedList(myUrls)=true {
(glob.match(myUrls[i], [], input.mysite.path))
}
Negation Example1
For safety, a variable appearing in a negated expression must also appear in another non-negated equality expression in the rule.
Following rule is rejected by OPA, since the variable greeting only appears in a negated expression.
Once we add the non-negated equality expression, it works.
Negation Example2
p[_]!=”foo” meaning at least one value from the set which is not “foo”
In order to check the set does not contain value “foo”, we can use not operator.
(Note: for a rule, when no assignment value is provided the assignment value of boolean true is implicitly assumed.)
package policy.role
import future.keywords.if
import future.keywords.containsp := ["line1", "line2", "line3", "foo"]contains_foo {
p[_] == "foo"
}default not_contains_foo := false
not_contains_foo {
not contains_foo
}contains_non_foo_value {
p[_] != "foo"
}
Negation Example 3
This example is similar to last one. Instead of working on a set vaiable, we put list of name to rule “myrule”.
package playimport future.keywords.if
import future.keywords.in
import future.keywords.containssites := [
{"name": "prod"},
{"name": "smoke1"},
{"name": "dev"}]myrule contains name if {
some site in sites
name := site.name
}# this rule is true
contains_prod {
myrule["prod"]
}# this rule is true
contains_non_prod {
myrule[_] != "prod"
}default not_contains_prod := false
# this rule is false
not_contains_prod {
not myrule["prod"]
}# this rule is true
not_contains_foo {
not myrule["foo"]
}
References
https://www.openpolicyagent.org/docs/v0.12.2/language-reference/#glob
https://www.openpolicyagent.org/docs/latest/policy-language/#functions
“RBAC with Rego https://github.com/orgs/open-policy-agent/discussions/319#discussioncomment-4981298”
package play
import future.keywords.contains
import future.keywords.if
import future.keywords.in
default allow := false
user_permissions contains permission if {
some role in input.user.roles
some permission in data.permissions[role]
}
required_permissions contains permission if {
some permission in data.resources[input.request.path].required_permissions
}
allow if object.subset(user_permissions, required_permissions)
“The Rego Playground (openpolicyagent.org)”
“logical and/or through incremental rules open policy agent — Using OR condition in OPA rego — Stack Overflow”
“recursive error: Profiling rego — rule reevaluation when returning data from it · open-policy-agent · Discussion #381 (github.com)”