Skip to main content

Rego Keyword: some

The some keyword is used to define a local variable for use later in a rule. The keyword can also used in conjunction with the in keyword to enumerate a series of items in a list or key value pairs in an object.

Examples

Some and in with arrays

In this example, we use some to select each item in an array, perform a check on it, and return matching items as a new array. Processing lists of values like this is one of the most common use cases for some.

data.json
{}
input.json
{}
policy.rego
package play

import rego.v1

example_array := [1, "example", 3]

filtered_array := [e |
some e in example_array

is_number(e)
]

Open in OPA Playground

RuleOutput Value
filtered_array[1,2]

Some and in with objects

Similar to arrays, some can also be used on key->value pairs in objects. Here, we create two variables, one for the key and another for the value. The Rego rule is then evaluated for each pair.

We can use the key and value however we like. Here, we use the name of the permission to create a list of permissions that are toggled on in the example_object.

data.json
{}
input.json
{}
policy.rego
package play

import rego.v1

example_object := {
"read": true,
"write": true,
"delete": false,
"create": false,
}

permission_list contains permission if {
some permission, value in example_object

value == true
}

Open in OPA Playground

RuleOutput Value
permission_list["read","write"]

Some for arbitrary iteration

The some keyword can also be used to instantiate variables used in arbitrary iteration. This is best practice as it makes it easier for readers to see which variables are used in each rule.

In the example below, some is used to declare i and j to search over a 2D array of requests from the past week. This data is then used to enforce a rate limiting policy on the new request from a user in the input.

policy.rego
package play

import rego.v1

limit_period := 3 # days

limit_count := 4 # requests

requests_in_period contains request if {
some i, j

i <= limit_period

request := data.last_weeks_requests[i][j]

request.user_id == input.user_id
}

default allow := false

allow if count(requests_in_period) <= limit_count

message := sprintf(
"user_id %d made %d requests in %d days, limit is %d",
[input.user_id, count(requests_in_period), limit_period, limit_count],
)
input.json
{
"request_id": 801,
"user_id": 1
}
data.json
{
"last_weeks_requests": [
[
{
"user_id": 1,
"request_id": 701
},
{
"user_id": 2,
"request_id": 702
},
{
"user_id": 3,
"request_id": 703
...

Open in OPA Playground

RuleOutput Value
allowfalse
message"user_id 1 made 4 requests in 3 days, limit is 4"