SlideShare une entreprise Scribd logo
1  sur  73
Télécharger pour lire hors ligne
Open Policy Agent
Language Introduction
openpolicyagent.org
OPA: Add fine-grained policy to other projects
OPA
Cloud
Orchestrator
Risk Management
Linux
Container Execution, SSH, sudo
OPA
Hashicorp
Terraform
OPA
Microservice APIs
Istio Linkerd
OPA
Placement &
Admission Control
openpolicyagent.org
Use OPA to policy-enable your project
Integrate
Offload policy decisions from your project to OPA
Author
Write OPA policies that make decisions
Manage
Deploy OPA, retrieve policy, audit decisions, monitor health
1
2
3
Agenda
● How Policies are Invoked
● Simple Policies
● Policies with Iteration
● Additional Topics
○ Modularity
○ Negation
○ Any/All
○ Non-boolean Decisions
How Policies are Invoked
● Overview
● Example:
○ HTTP API Authorization
openpolicyagent.org
How Policies are Invoked
DataLogic
openpolicyagent.org
How Policies are Invoked
DataLogic
POST v1/data/<policy-name>
{“input”: <JSON>}
1. Decision Request
Any JSON value:
● "alice"
● ["api", "v1", "cars"]
● {"headers": {...}}
openpolicyagent.org
How Policies are Invoked
DataLogic
200 OK
{“result”: <JSON>}
1. Decision Request 2. Decision Response
Any JSON value:
● true, false
● "bob"
● {"servers": ["server-001", …]}
POST v1/data/<policy-name>
{“input”: <JSON>}
Any JSON value:
● "alice"
● ["api", "v1", "cars"]
● {"headers": {...}}
openpolicyagent.org
How Policies are Invoked
DataLogic
200 OK
{“result”: <JSON>}
Input is JSON. Policy decision is JSON.
1. Decision Request 2. Decision Response
POST v1/data/<policy-name>
{“input”: <JSON>}
Any JSON value:
● true, false
● "bob"
● {"servers": ["server-001", …]}
Any JSON value:
● "alice"
● ["api", "v1", "cars"]
● {"headers": {...}}
openpolicyagent.org
Example: HTTP API Authorization
DataLogic
openpolicyagent.org
Example: HTTP API Authorization
DataLogic
1. Example Request to OPA
POST v1/data/http/authz/allow
{"input": {
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"}}
1
openpolicyagent.org
Example: HTTP API Authorization
DataLogic
1. Example Request to OPA
2. Example Policy in OPA
POST v1/data/http/authz/allow
{"input": {
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"}}
package http.authz
allow {
input.user == “bob”
}
1
2
openpolicyagent.org
Example: HTTP API Authorization
DataLogic
1. Example Request to OPA
2. Example Policy in OPA
3. Example Response from OPA
POST v1/data/http/authz/allow
{"input": {
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"}}
package http.authz
allow {
input.user == “bob”
}
{“result”: true}
1
2
3
Agenda
● How Policies are Invoked
● Simple Policies
● Policies with Iteration
● Additional Topics
○ Modularity
○ Negation
○ Non-boolean Decisions
Simple Policies
● Lookup values
● Compare values
● Assign values
● Create rules
● Create functions
● Use context (data)
openpolicyagent.org
Lookup and Compare Values
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Input
input.method
input.path[0]
Lookup values.
openpolicyagent.org
Lookup and Compare Values
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Input
input.method == “GET”
input.path[0] == “finance”
input.user != input.method
Lookup values. Compare values.
openpolicyagent.org
Lookup and Compare Values
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Input
input.method == “GET”
input.path[0] == “finance”
input.user != input.method
startswith(input.path[1], “sal”)
count(input.path) > 2
Lookup values. Compare values.
See 50+ operators documented at openpolicyagent.org/docs/language-reference.html
openpolicyagent.org
path := input.path
path[2] == "alice"
Assign Values to Variables
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Input Assign variables.
Use variables like input.
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules have a Head and a Body.
allow = true {
input.method == "GET"
input.user == "bob"
}
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules have a Head and a Body.
allow = true {
input.method == "GET"
input.user == "bob"
}
Rule Head
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules have a Head and a Body.
allow = true {
input.method == "GET"
input.user == "bob"
}
Rule Head
Name allow
Value true
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules have a Head and a Body.
allow {
input.method == "GET"
input.user == "bob"
}
Rule Head
Name allow
Value true
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules have a Head and a Body.
allow {
input.method == "GET"
input.user == "bob"
}
Rule Body
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules have a Head and a Body.
allow {
input.method == "GET"
input.user == "bob"
}
Rule Body
Multiple statements
in rule body
are ANDed together.
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules have a Head and a Body.
allow {
input.method == "GET"
input.user == "bob"
}
Rule Body
Multiple statements
in rule body
are ANDed together.
allow is true IF
input.method equals "GET" AND
input.user equals "bob"
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Multiple rules with same name.
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}
openpolicyagent.org
Input
Create Rules
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Multiple rules with same name.
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}Rule Head
Multiple statements
with same head
are ORed together.
openpolicyagent.org
Create Rules
Input
{
"method": "POST",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules can be undefined.
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}
openpolicyagent.org
Create Rules
Input
{
"method": "POST",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules can be undefined.
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}
Different method.
"POST" instead of "GET"
openpolicyagent.org
Create Rules
Input
{
"method": "POST",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Rules can be undefined.
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}
Different method.
"POST" instead of "GET"
Neither rule matches.
allow is undefined (not false!)
openpolicyagent.org
Create Rules
Input
{
"method": "POST",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Use default keyword.
default allow = false
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}
openpolicyagent.org
Create Rules
Input
{
"method": "POST",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Use default keyword.
default allow = false
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}
default <name> = <value>
If no rules match
default value is returned.
openpolicyagent.org
Create Rules
Input
{
"method": "POST",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Use default keyword.
default allow = false
allow {
input.method == "GET"
input.user == "bob"
}
allow {
input.method == "GET"
input.user == input.path[2]
}
default <name> = <value>
If no rules match
default value is returned.
at most one default per rule set
openpolicyagent.org
Create Functions
Input
{
"method": "GET",
"path": "/finance/salary/alice",
"user": "bob"
}
Path is a string now.
openpolicyagent.org
Create Functions
Input
{
"method": "GET",
"path": "/finance/salary/alice",
"user": "bob"
}
Example rule
default allow = false
allow {
trimmed := trim(input.path, "/")
path := split(trimmed, "/")
path = ["finance", "salary", user]
input.user == user
}
Path is a string now.
openpolicyagent.org
{
"method": "GET",
"path": "/finance/salary/alice",
"user": "bob"
}
Create Functions
Input Example rule
default allow = false
allow {
trimmed := trim(input.path, "/")
path := split(trimmed, "/")
path = ["finance", "salary", user]
input.user == user
}
Path is a string now.
Avoid duplicating
common logic like
string manipulation
openpolicyagent.org
{
"method": "GET",
"path": "/finance/salary/alice",
"user": "bob"
}
Create Functions
Input Put common logic into functions
default allow = false
allow {
path := split_path(input.path)
path = ["finance", "salary", user]
input.user == user
}
split_path(str) = parts {
trimmed := trim(str, "/")
parts := split(trimmed, "/")
}
Path is a string now.
Avoid duplicating
common logic like
string manipulation
openpolicyagent.org
{
"method": "GET",
"path": "/finance/salary/alice",
"user": "bob"
}
Create Functions
Input Functions are Rules with arguments.
read_method(str) = true {
str == "GET"
}
read_method(str) = true {
str == "HEAD"
}
openpolicyagent.org
{
"method": "GET",
"path": "/finance/salary/alice",
"user": "bob"
}
Create Functions
Input Functions are Rules with arguments.
read_method(str) = true {
str == "GET"
}
read_method(str) = true {
str == "HEAD"
}
"Function" Head
Multiple statements
with same head
are ORed together.
openpolicyagent.org
{
"method": "GET",
"path": "/finance/salary/alice",
"user": "bob"
}
Create Functions
Input Functions are Rules with arguments.
read_method(str) {
str == "GET"
}
read_method(str) {
str == "HEAD"
}
"Function" Head
Multiple statements
with same head
are ORed together.
openpolicyagent.org
Policies can use Context from Outside World
PUT v1/data/<path> HTTP/1.1
Content-Type: application/json
<JSON>
Load Context/Data Into OPA
DataLogic
openpolicyagent.org
{
"users": {
"alice": {"department": "legal"},
"bob": {"department": "hr"},
"janet": {"department": "r&d"}
}
}
{
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"
}
Policies Use Context
Data (context)
Policy
allow {
# Users can access their own salary
input.user == input.path[2]
}
allow {
# HR can access any salary
user := data.users[input.user]
user.department == "hr"
}
Input
openpolicyagent.org
Summary
Lookup values input.path[1]
Compare values "bob" == input.user
Assign values user := input.user
Rules <head> { <body> }
Rule Head <name> = <value> { … } or <name> { … }
Rule Body <statement-1>; <statement-2>; … (ANDed)
Multiple Rules with same name <rule-1> OR <rule-2> OR ...
Default Rule Value default <name> = <value>
Functions Rules with arguments
Context Reference with data. instead of input.
Agenda
● How Policies are Invoked
● Simple Policies
● Policies with Iteration
● Additional Topics
○ Modularity
○ Negation
○ Any/All
○ Non-boolean Decisions
Policies With Iteration
● Iteration
● Virtual documents
● Virtual documents vs Functions
openpolicyagent.org
{
"resources": [
{"id": "54cf10", "owner": "alice"},
{"id": "3df429": "owner": "bob"}
...
],
...
}
# allow if resource is at element 0
allow {
input.resource == data.resources[0].id
input.user == data.resources[0].owner
}
What about Arrays?
Allow if user owns resource.
Not sure where resource is in array
{
"user": "alice"
"resource": "54cf10",
}
Input
Data
openpolicyagent.org
{
"resources": [
{"id": "54cf10", "owner": "alice"},
{"id": "3df429": "owner": "bob"}
...
],
...
}
# allow if resource is at element 0
allow {
input.resource == data.resources[0].id
input.user == data.resources[0].owner
}
# OR if resource is at element 1
allow {
input.resource == data.resources[1].id
input.user == data.resources[1].owner
}
What about Arrays?
Allow if user owns resource.
Not sure where resource is in array
{
"user": "alice"
"resource": "54cf10",
}
Input
Data
openpolicyagent.org
{
"resources": [
{"id": "54cf10", "owner": "alice"},
{"id": "3df429": "owner": "bob"}
...
],
...
}
# allow if resource is at element 0
allow {
input.resource == data.resources[0].id
input.user == data.resources[0].owner
}
# OR if resource is at element 1
allow {
input.resource == data.resources[1].id
input.user == data.resources[1].owner
}
...
What about Arrays?
Allow if user owns resource.
Not sure where resource is in array
{
"user": "alice"
"resource": "54cf10",
}
Input
Data
Problem: Unknown number of elements.
Cannot write allow for every index.
openpolicyagent.org
{
"resources": [
{"id": "54cf10", "owner": "alice"},
{"id": "3df429": "owner": "bob"}
...
],
...
}
# allow if resource is anywhere in array
allow {
input.resource == data.resources[index].id
input.user == data.resources[index].owner
}
Iterate over Arrays
Allow if user owns resource.
Not sure where resource is in array
{
"user": "alice"
"resource": "54cf10",
}
Input
Data
openpolicyagent.org
{
"resources": [
{"id": "54cf10", "owner": "alice"},
{"id": "3df429": "owner": "bob"}
...
],
...
}
# allow if resource is anywhere in array
allow {
input.resource == data.resources[index].id
input.user == data.resources[index].owner
}
Iterate over Arrays
Allow if user owns resource.
Not sure where resource is in array
{
"user": "alice"
"resource": "54cf10",
}
Input
Data
Solution:
● allow is true if SOME value for index makes
the rule body true.
● OPA automatically iterates over values for
index.
● allow is true for index = 0
openpolicyagent.org
Iterate over Everything
Iterate over arrays/dictionaries (whether input or data)
# Iterate over array indexes/values
resource_obj := data.resources[index]
# Iterate over dictionary key/values
user_obj := data.users[name]
# Doesn’t matter whether input or data
value := input[key]
# Use _ to ignore variable name
# Iterate over just the array values
resource_obj := data.resources[_]
{
"method": "GET",
"path": ["resources", "54cf10"],
"user": "bob"
}
Input
{
"resources": [
{"id": "54cf10", "owner": "alice"},
{"id": "3df429": "owner": "bob"}
],
"users": {
"alice": {"admin": false},
"bob": {"admin": true},
"charlie": {"admin": true},
}
}
Data
openpolicyagent.org
Duplicated Logic Happens with Iteration too
{
“users”: [
{"name": "alice", "admin": false, “dept”: “eng”},
{"name": "bob", "admin": true, “dept”: “hr”},
{"name": "charlie", "admin": true, “dept”: “eng”},
}
}
Data
allow {
user := data.users[_]
user.admin == true
user.name == input.user
input.method == “GET”
}
allow {
user := data.users[_]
user.admin == true
user.name == input.user
input.method == “POST”
}
Duplicated logic with iteration
openpolicyagent.org
Duplicated Logic Happens with Iteration too
{
“users”: [
{"name": "alice", "admin": false, “dept”: “eng”},
{"name": "bob", "admin": true, “dept”: “hr”},
{"name": "charlie", "admin": true, “dept”: “eng”},
}
}
Data
allow {
user := data.users[_]
user.admin == true
user.name == input.user
input.method == “GET”
}
allow {
user := data.users[_]
user.admin == true
user.name == input.user
input.method == “POST”
}
Duplicated logic with iteration
Avoid duplicating
common logic like a
search for admins
openpolicyagent.org
Create a Virtual Document
{
“users”: [
{"name": "alice", "admin": false, “dept”: “eng”},
{"name": "bob", "admin": true, “dept”: “hr”},
{"name": "charlie", "admin": true, “dept”: “eng”},
}
}
Data
allow {
admin[input.user]
input.method == “GET”
}
allow {
admin[input.user]
input.method == “POST”
}
admin[user.name] {
user := data.users[_]
user.admin == true
}
Duplicated logic with iteration
admin is a set that contains all of the admin names
Sets are an extension of JSON.
admin == { "bob", "charlie" }
openpolicyagent.org
Different Syntaxes for Virtual Sets
{
“users”: [
{"name": "alice", "admin": false, “dept”: “eng”},
{"name": "bob", "admin": true, “dept”: “hr”},
{"name": "charlie", "admin": true, “dept”: “eng”},
}
}
admin[user.name] {
user := data.users[_]
user.admin == true
}
Data Rule Syntax
admin = {user.name |
user := data.users[_]
user.admin == true
}
Set Comprehension Syntax
openpolicyagent.org
Different Syntaxes for Virtual Sets
{
“users”: [
{"name": "alice", "admin": false, “dept”: “eng”},
{"name": "bob", "admin": true, “dept”: “hr”},
{"name": "charlie", "admin": true, “dept”: “eng”},
}
}
admin[user.name] {
user := data.users[_]
user.admin == true
}
Data Rule Syntax
admin = {user.name |
user := data.users[_]
user.admin == true
}
Set Comprehension Syntax
Supports OR with
multiple rules.
No support for OR.
openpolicyagent.org
Create Virtual Dictionaries too
{
“users”: [
{"name": "alice", "admin": false, “dept”: “eng”},
{"name": "bob", "admin": true, “dept”: “hr”},
{"name": "charlie", "admin": true, “dept”: “eng”},
}
}
Data
admin[user.name] = user.dept {
user := data.users[_]
user.admin == true
}
Rule Syntax
admin = {user.name: user.dept |
user := data.users[_]
user.admin == true
}
Dictionary Comprehension Syntax
openpolicyagent.org
Virtual Docs support iteration. Functions don’t.
admin[user_name] = user.dept {
user := data.users[_]
user.admin == true
user.name == user_name
}
admin(user_name) = user.dept {
user := data.users[_]
user.admin == true
user.name == user_name
}
Dictionary Function
# lookup bob’s department
admin[“bob”]
# iterate over all user/dept pairs
admin[user] = department
# iterate over everyone in HR
admin[user] == “hr”
# lookup bob’s department
admin(“bob”)
# iterate over all user/dept pairs
Can’t. Write different function.
# iterate over everyone in HR
Can’t.
openpolicyagent.org
Virtual Documents must be finite. Functions don’t.
Can’t express split_path.
Virtual docs must be “safe”.
Safety means the set of all
input/output pairs is finite.
split_path takes any string as
input. There are infinitely
strings.
split_path(str) = parts {
trimmed := trim(str, "/")
parts := split(trimmed, "/")
}
Virtual Doc Function
Agenda
● How Policies are Invoked
● Simple Policies
● Policies with Iteration
● Additional Topics
○ Modularity
○ Negation
○ Any/All
○ Non-boolean Decisions
openpolicyagent.org
People can Create Multiple Policies and Delegate
package http.service_graph
allow {
input.source == “frontend”
input.destination == “finance”
}
...
Service graph policy
package http.org_chart
allow {
admin[user.input]
}
...
Organization chart policy
package http.authz
import data.http.service_graph
import data.http.org_chart
allow {
org_chart.allow
service_graph.allow
}
Entry point policy
openpolicyagent.org
Policies can use Negation
package http.service_graph
deny {
input.source == “frontend”
input.destination == “finance”
}
...
Service graph policy
package http.org_chart
allow {
admin[user.input]
}
Organization chart policy
package http.authz
import data.http.service_graph
import data.http.org_chart
allow {
org_chart.allow
not service_graph.deny
not deny
}
deny { ... }
Entry point policy
openpolicyagent.org
{
“users”: {
"alice": {"admin": false, “org_code”: “11”},
"bob": {"admin": true, “org_code”: “22”},
"charlie": {"admin": true, “org_code”: “33”}
}
}
Any vs. All
Data Check if all users are admins. Wrong ans:
all_admins = true {
data.users[user_name].admin == true
}
openpolicyagent.org
{
“users”: {
"alice": {"admin": false, “org_code”: “11”},
"bob": {"admin": true, “org_code”: “22”},
"charlie": {"admin": true, “org_code”: “33”}
}
}
Any vs. All
Data Check if all users are admins. Wrong ans:
all_admins = true {
data.users[user_name].admin == true
}
Problem: all_admins is true if ANY users are admins.
openpolicyagent.org
{
“users”: {
"alice": {"admin": false, “org_code”: “11”},
"bob": {"admin": true, “org_code”: “22”},
"charlie": {"admin": true, “org_code”: “33”}
}
}
Any vs. All
Data Check if all users are admins.
all_admins = true {
not any_non_admins
}
any_non_admins = true {
user := data.users[user_name]
not user.admin
}
Solution:
1. Check if any users
are NOT admins
2. Complement (1)
openpolicyagent.org
{
“users”: {
"alice": {"admin": false, “org_code”: “11”},
"bob": {"admin": true, “org_code”: “22”},
"charlie": {"admin": true, “org_code”: “33”}
}
}
Any vs. All
Data Check if all users are admins.
all_admins = true {
not any_non_admins
}
any_non_admins = true {
user := data.users[user_name]
not user.admin
}
Solution:
1. Check if any users
are NOT admins
2. Complement (1)
openpolicyagent.org
allow/deny are NOT special. Decisions are JSON
DataLogic
POST v1/data/http/authz/admin
{"input": {
"method": "GET",
"path": ["finance", "salary", "alice"],
"user": "bob"}}
2. Example Policy
1. Example Request
3. Example Response
{“result”: [“bob”, “charlie”]}
package http.authz
import data.http.service_graph
import data.http.org_chart
admin[x] {
org_chart.admin[x]
}
admin[x] {
service_graph.admin[x]
}
Sets defined with
multiple rules
are unioned together.
Policy decision can be any
JSON data: boolean, number,
string, null, array, or dictionary.
Sets are serialized to JSON
arrays.
openpolicyagent.org
Thank You!
github.com/open-policy-agent/opa
slack.openpolicyagent.org
openpolicyagent.org
Policy Example with Join
openpolicyagent.org
Policies Iterate to Search for Data
{
“users”: {
"alice": {"admin": false, “org_code”: “11”},
"bob": {"admin": true, “org_code”: “22”},
"charlie": {"admin": true, “org_code”: “33”}
},
“orgs”: {
“00”: {“name”: “HR”},
“11”: {“name”: “Legal”},
“22”: {“name”: “Research”},
“33”: {“name”: “IT”},
“44”: {“name”: “Accounting”},
}
}
Data Search for the data you need
user_obj user_name org_name
{"admin": true, ...} bob Research
{"admin": true, ...} charlie IT
# Find admin users and their organization
user_obj := data.users[user_name];
user_obj.admin == true;
org_name := data.orgs[user_obj.org_code].name
Variable assignments that satisfy search criteria
openpolicyagent.org
Policies Give Names to Search Results
Data Name the search results
admins[[org_name, user_name]] {
user_obj := data.users[user_name]
user_obj.admin == true
org_name := data.orgs[user_obj.org_code].name
}
{
“users”: {
"alice": {"admin": false, “org_code”: “11”},
"bob": {"admin": true, “org_code”: “22”},
"charlie": {"admin": true, “org_code”: “33”}
},
“orgs”: {
“00”: {“name”: “HR”},
“11”: {“name”: “Legal”},
“22”: {“name”: “Research”},
“33”: {“name”: “IT”},
“44”: {“name”: “Accounting”},
}
}
admins is a set that contains
all of the [org_name, user_name] pairs
that make the body true.
admins == {
["Research", "bob"],
["IT", "charlie"],
}
openpolicyagent.org
Policies Apply Search Results to Make Decisions
Input
{
“users”: {
"alice": {"admin": false, “org_code”: “11”},
"bob": {"admin": true, “org_code”: “22”},
"charlie": {"admin": true, “org_code”: “33”}
},
“orgs”: {
“00”: {“name”: “HR”},
“11”: {“name”: “Legal”},
“22”: {“name”: “Research”},
...
Apply the search results
allow {
# allow admins to do everything
admins[[_, input.user]]
}
admins[[org_name, user_name]] {
user_obj := data.users[user_name]
user_obj.admin == true
org_name := data.orgs[user_obj.org_code].name
}
Check if bob is an admin
Lookup IT admins
Iterate over all pairs
admins[[_, “bob”]]
admins[[“IT”, name]]
admins[x]
{
"method": "GET",
"path": ["resources", "54cf10"],
"user": "bob"
}
Data

Contenu connexe

Tendances

Implementing Authorization
Implementing AuthorizationImplementing Authorization
Implementing AuthorizationTorin Sandall
 
OPA APIs and Use Case Survey
OPA APIs and Use Case SurveyOPA APIs and Use Case Survey
OPA APIs and Use Case SurveyTorin Sandall
 
Opa gatekeeper
Opa gatekeeperOpa gatekeeper
Opa gatekeeperRita Zhang
 
JSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataJSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataGregg Kellogg
 
An Introduction to OAuth 2
An Introduction to OAuth 2An Introduction to OAuth 2
An Introduction to OAuth 2Aaron Parecki
 
Policy Enforcement on Kubernetes with Open Policy Agent
Policy Enforcement on Kubernetes with Open Policy AgentPolicy Enforcement on Kubernetes with Open Policy Agent
Policy Enforcement on Kubernetes with Open Policy AgentVMware Tanzu
 
Secure your app with keycloak
Secure your app with keycloakSecure your app with keycloak
Secure your app with keycloakGuy Marom
 
Istio's mixer policy enforcement with custom adapters (cloud nativecon 17)
Istio's mixer  policy enforcement with custom adapters (cloud nativecon 17)Istio's mixer  policy enforcement with custom adapters (cloud nativecon 17)
Istio's mixer policy enforcement with custom adapters (cloud nativecon 17)Torin Sandall
 
DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)
DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)
DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)Michael Man
 
OAuth2 - Introduction
OAuth2 - IntroductionOAuth2 - Introduction
OAuth2 - IntroductionKnoldus Inc.
 
Rest api standards and best practices
Rest api standards and best practicesRest api standards and best practices
Rest api standards and best practicesAnkita Mahajan
 
Building secure applications with keycloak
Building secure applications with keycloak Building secure applications with keycloak
Building secure applications with keycloak Abhishek Koserwal
 
Clean architectures with fast api pycones
Clean architectures with fast api   pyconesClean architectures with fast api   pycones
Clean architectures with fast api pyconesAlvaro Del Castillo
 
Integrating Fiware Orion, Keyrock and Wilma
Integrating Fiware Orion, Keyrock and WilmaIntegrating Fiware Orion, Keyrock and Wilma
Integrating Fiware Orion, Keyrock and WilmaDalton Valadares
 
An Introduction to OAuth2
An Introduction to OAuth2An Introduction to OAuth2
An Introduction to OAuth2Aaron Parecki
 
Overview of API Management Architectures
Overview of API Management ArchitecturesOverview of API Management Architectures
Overview of API Management ArchitecturesNordic APIs
 
Kubernetes Security with Calico and Open Policy Agent
Kubernetes Security with Calico and Open Policy AgentKubernetes Security with Calico and Open Policy Agent
Kubernetes Security with Calico and Open Policy AgentCloudOps2005
 

Tendances (20)

Implementing Authorization
Implementing AuthorizationImplementing Authorization
Implementing Authorization
 
OPA APIs and Use Case Survey
OPA APIs and Use Case SurveyOPA APIs and Use Case Survey
OPA APIs and Use Case Survey
 
Opa gatekeeper
Opa gatekeeperOpa gatekeeper
Opa gatekeeper
 
JSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked DataJSON-LD: JSON for Linked Data
JSON-LD: JSON for Linked Data
 
An Introduction to OAuth 2
An Introduction to OAuth 2An Introduction to OAuth 2
An Introduction to OAuth 2
 
Policy Enforcement on Kubernetes with Open Policy Agent
Policy Enforcement on Kubernetes with Open Policy AgentPolicy Enforcement on Kubernetes with Open Policy Agent
Policy Enforcement on Kubernetes with Open Policy Agent
 
Secure your app with keycloak
Secure your app with keycloakSecure your app with keycloak
Secure your app with keycloak
 
Istio's mixer policy enforcement with custom adapters (cloud nativecon 17)
Istio's mixer  policy enforcement with custom adapters (cloud nativecon 17)Istio's mixer  policy enforcement with custom adapters (cloud nativecon 17)
Istio's mixer policy enforcement with custom adapters (cloud nativecon 17)
 
DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)
DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)
DSO-LG 2021 Reboot: Policy As Code (Anders Eknert)
 
OAuth2 - Introduction
OAuth2 - IntroductionOAuth2 - Introduction
OAuth2 - Introduction
 
Rest api standards and best practices
Rest api standards and best practicesRest api standards and best practices
Rest api standards and best practices
 
Building secure applications with keycloak
Building secure applications with keycloak Building secure applications with keycloak
Building secure applications with keycloak
 
OAuth
OAuthOAuth
OAuth
 
Clean architectures with fast api pycones
Clean architectures with fast api   pyconesClean architectures with fast api   pycones
Clean architectures with fast api pycones
 
OAuth 2.0
OAuth 2.0OAuth 2.0
OAuth 2.0
 
Integrating Fiware Orion, Keyrock and Wilma
Integrating Fiware Orion, Keyrock and WilmaIntegrating Fiware Orion, Keyrock and Wilma
Integrating Fiware Orion, Keyrock and Wilma
 
An Introduction to OAuth2
An Introduction to OAuth2An Introduction to OAuth2
An Introduction to OAuth2
 
Overview of API Management Architectures
Overview of API Management ArchitecturesOverview of API Management Architectures
Overview of API Management Architectures
 
Kubernetes Security with Calico and Open Policy Agent
Kubernetes Security with Calico and Open Policy AgentKubernetes Security with Calico and Open Policy Agent
Kubernetes Security with Calico and Open Policy Agent
 
OAuth2 + API Security
OAuth2 + API SecurityOAuth2 + API Security
OAuth2 + API Security
 

Similaire à Rego Deep Dive

Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4DEVCON
 
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastAtlassian
 
2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauth2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauthikailan
 
The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009Chris Chabot
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreStormpath
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreNate Barbettini
 
Connect Intergration Patterns: A Case Study - Patrick Streule
Connect Intergration Patterns: A Case Study - Patrick StreuleConnect Intergration Patterns: A Case Study - Patrick Streule
Connect Intergration Patterns: A Case Study - Patrick StreuleAtlassian
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)David Rodenas
 
Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4DEVCON
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using DjangoNathan Eror
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for BeginnersJason Davies
 
Dynamic Authorization & Policy Control for Docker Environments
Dynamic Authorization & Policy Control for Docker EnvironmentsDynamic Authorization & Policy Control for Docker Environments
Dynamic Authorization & Policy Control for Docker EnvironmentsTorin Sandall
 
PHP Server side restful API - linkedin
PHP Server side restful API - linkedinPHP Server side restful API - linkedin
PHP Server side restful API - linkedinVũ Quang Sơn
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSMartin Hochel
 
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Stamatis Zampetakis
 
Gaelyk: Lightweight Groovy on the Google App Engine
Gaelyk: Lightweight Groovy on the Google App EngineGaelyk: Lightweight Groovy on the Google App Engine
Gaelyk: Lightweight Groovy on the Google App EngineTim Berglund
 
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect ModelComprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect ModelvodQA
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsDylan Jay
 
MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...
MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...
MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...Jitendra Bafna
 

Similaire à Rego Deep Dive (20)

Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
 
2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauth2011 august-gdd-mexico-city-rest-json-oauth
2011 august-gdd-mexico-city-rest-json-oauth
 
The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009The Open & Social Web - Kings of Code 2009
The Open & Social Web - Kings of Code 2009
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
Connect Intergration Patterns: A Case Study - Patrick Streule
Connect Intergration Patterns: A Case Study - Patrick StreuleConnect Intergration Patterns: A Case Study - Patrick Streule
Connect Intergration Patterns: A Case Study - Patrick Streule
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)
 
Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 
Dynamic Authorization & Policy Control for Docker Environments
Dynamic Authorization & Policy Control for Docker EnvironmentsDynamic Authorization & Policy Control for Docker Environments
Dynamic Authorization & Policy Control for Docker Environments
 
PHP Server side restful API - linkedin
PHP Server side restful API - linkedinPHP Server side restful API - linkedin
PHP Server side restful API - linkedin
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJS
 
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21
 
Gaelyk: Lightweight Groovy on the Google App Engine
Gaelyk: Lightweight Groovy on the Google App EngineGaelyk: Lightweight Groovy on the Google App Engine
Gaelyk: Lightweight Groovy on the Google App Engine
 
Android Data Binding from zero
Android Data Binding from zeroAndroid Data Binding from zero
Android Data Binding from zero
 
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect ModelComprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web apps
 
MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...
MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...
MuleSoft Surat Live Demonstration Virtual Meetup#5 - Salesforce Composite Con...
 

Dernier

The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 

Dernier (20)

The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 

Rego Deep Dive

  • 2. openpolicyagent.org OPA: Add fine-grained policy to other projects OPA Cloud Orchestrator Risk Management Linux Container Execution, SSH, sudo OPA Hashicorp Terraform OPA Microservice APIs Istio Linkerd OPA Placement & Admission Control
  • 3. openpolicyagent.org Use OPA to policy-enable your project Integrate Offload policy decisions from your project to OPA Author Write OPA policies that make decisions Manage Deploy OPA, retrieve policy, audit decisions, monitor health 1 2 3
  • 4. Agenda ● How Policies are Invoked ● Simple Policies ● Policies with Iteration ● Additional Topics ○ Modularity ○ Negation ○ Any/All ○ Non-boolean Decisions
  • 5. How Policies are Invoked ● Overview ● Example: ○ HTTP API Authorization
  • 7. openpolicyagent.org How Policies are Invoked DataLogic POST v1/data/<policy-name> {“input”: <JSON>} 1. Decision Request Any JSON value: ● "alice" ● ["api", "v1", "cars"] ● {"headers": {...}}
  • 8. openpolicyagent.org How Policies are Invoked DataLogic 200 OK {“result”: <JSON>} 1. Decision Request 2. Decision Response Any JSON value: ● true, false ● "bob" ● {"servers": ["server-001", …]} POST v1/data/<policy-name> {“input”: <JSON>} Any JSON value: ● "alice" ● ["api", "v1", "cars"] ● {"headers": {...}}
  • 9. openpolicyagent.org How Policies are Invoked DataLogic 200 OK {“result”: <JSON>} Input is JSON. Policy decision is JSON. 1. Decision Request 2. Decision Response POST v1/data/<policy-name> {“input”: <JSON>} Any JSON value: ● true, false ● "bob" ● {"servers": ["server-001", …]} Any JSON value: ● "alice" ● ["api", "v1", "cars"] ● {"headers": {...}}
  • 10. openpolicyagent.org Example: HTTP API Authorization DataLogic
  • 11. openpolicyagent.org Example: HTTP API Authorization DataLogic 1. Example Request to OPA POST v1/data/http/authz/allow {"input": { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob"}} 1
  • 12. openpolicyagent.org Example: HTTP API Authorization DataLogic 1. Example Request to OPA 2. Example Policy in OPA POST v1/data/http/authz/allow {"input": { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob"}} package http.authz allow { input.user == “bob” } 1 2
  • 13. openpolicyagent.org Example: HTTP API Authorization DataLogic 1. Example Request to OPA 2. Example Policy in OPA 3. Example Response from OPA POST v1/data/http/authz/allow {"input": { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob"}} package http.authz allow { input.user == “bob” } {“result”: true} 1 2 3
  • 14. Agenda ● How Policies are Invoked ● Simple Policies ● Policies with Iteration ● Additional Topics ○ Modularity ○ Negation ○ Non-boolean Decisions
  • 15. Simple Policies ● Lookup values ● Compare values ● Assign values ● Create rules ● Create functions ● Use context (data)
  • 16. openpolicyagent.org Lookup and Compare Values { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Input input.method input.path[0] Lookup values.
  • 17. openpolicyagent.org Lookup and Compare Values { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Input input.method == “GET” input.path[0] == “finance” input.user != input.method Lookup values. Compare values.
  • 18. openpolicyagent.org Lookup and Compare Values { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Input input.method == “GET” input.path[0] == “finance” input.user != input.method startswith(input.path[1], “sal”) count(input.path) > 2 Lookup values. Compare values. See 50+ operators documented at openpolicyagent.org/docs/language-reference.html
  • 19. openpolicyagent.org path := input.path path[2] == "alice" Assign Values to Variables { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Input Assign variables. Use variables like input.
  • 20. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Rules have a Head and a Body. allow = true { input.method == "GET" input.user == "bob" }
  • 21. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Rules have a Head and a Body. allow = true { input.method == "GET" input.user == "bob" } Rule Head
  • 22. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Rules have a Head and a Body. allow = true { input.method == "GET" input.user == "bob" } Rule Head Name allow Value true
  • 23. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Rules have a Head and a Body. allow { input.method == "GET" input.user == "bob" } Rule Head Name allow Value true
  • 24. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Rules have a Head and a Body. allow { input.method == "GET" input.user == "bob" } Rule Body
  • 25. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Rules have a Head and a Body. allow { input.method == "GET" input.user == "bob" } Rule Body Multiple statements in rule body are ANDed together.
  • 26. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Rules have a Head and a Body. allow { input.method == "GET" input.user == "bob" } Rule Body Multiple statements in rule body are ANDed together. allow is true IF input.method equals "GET" AND input.user equals "bob"
  • 27. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Multiple rules with same name. allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] }
  • 28. openpolicyagent.org Input Create Rules { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Multiple rules with same name. allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] }Rule Head Multiple statements with same head are ORed together.
  • 29. openpolicyagent.org Create Rules Input { "method": "POST", "path": ["finance", "salary", "alice"], "user": "bob" } Rules can be undefined. allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] }
  • 30. openpolicyagent.org Create Rules Input { "method": "POST", "path": ["finance", "salary", "alice"], "user": "bob" } Rules can be undefined. allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] } Different method. "POST" instead of "GET"
  • 31. openpolicyagent.org Create Rules Input { "method": "POST", "path": ["finance", "salary", "alice"], "user": "bob" } Rules can be undefined. allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] } Different method. "POST" instead of "GET" Neither rule matches. allow is undefined (not false!)
  • 32. openpolicyagent.org Create Rules Input { "method": "POST", "path": ["finance", "salary", "alice"], "user": "bob" } Use default keyword. default allow = false allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] }
  • 33. openpolicyagent.org Create Rules Input { "method": "POST", "path": ["finance", "salary", "alice"], "user": "bob" } Use default keyword. default allow = false allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] } default <name> = <value> If no rules match default value is returned.
  • 34. openpolicyagent.org Create Rules Input { "method": "POST", "path": ["finance", "salary", "alice"], "user": "bob" } Use default keyword. default allow = false allow { input.method == "GET" input.user == "bob" } allow { input.method == "GET" input.user == input.path[2] } default <name> = <value> If no rules match default value is returned. at most one default per rule set
  • 35. openpolicyagent.org Create Functions Input { "method": "GET", "path": "/finance/salary/alice", "user": "bob" } Path is a string now.
  • 36. openpolicyagent.org Create Functions Input { "method": "GET", "path": "/finance/salary/alice", "user": "bob" } Example rule default allow = false allow { trimmed := trim(input.path, "/") path := split(trimmed, "/") path = ["finance", "salary", user] input.user == user } Path is a string now.
  • 37. openpolicyagent.org { "method": "GET", "path": "/finance/salary/alice", "user": "bob" } Create Functions Input Example rule default allow = false allow { trimmed := trim(input.path, "/") path := split(trimmed, "/") path = ["finance", "salary", user] input.user == user } Path is a string now. Avoid duplicating common logic like string manipulation
  • 38. openpolicyagent.org { "method": "GET", "path": "/finance/salary/alice", "user": "bob" } Create Functions Input Put common logic into functions default allow = false allow { path := split_path(input.path) path = ["finance", "salary", user] input.user == user } split_path(str) = parts { trimmed := trim(str, "/") parts := split(trimmed, "/") } Path is a string now. Avoid duplicating common logic like string manipulation
  • 39. openpolicyagent.org { "method": "GET", "path": "/finance/salary/alice", "user": "bob" } Create Functions Input Functions are Rules with arguments. read_method(str) = true { str == "GET" } read_method(str) = true { str == "HEAD" }
  • 40. openpolicyagent.org { "method": "GET", "path": "/finance/salary/alice", "user": "bob" } Create Functions Input Functions are Rules with arguments. read_method(str) = true { str == "GET" } read_method(str) = true { str == "HEAD" } "Function" Head Multiple statements with same head are ORed together.
  • 41. openpolicyagent.org { "method": "GET", "path": "/finance/salary/alice", "user": "bob" } Create Functions Input Functions are Rules with arguments. read_method(str) { str == "GET" } read_method(str) { str == "HEAD" } "Function" Head Multiple statements with same head are ORed together.
  • 42. openpolicyagent.org Policies can use Context from Outside World PUT v1/data/<path> HTTP/1.1 Content-Type: application/json <JSON> Load Context/Data Into OPA DataLogic
  • 43. openpolicyagent.org { "users": { "alice": {"department": "legal"}, "bob": {"department": "hr"}, "janet": {"department": "r&d"} } } { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob" } Policies Use Context Data (context) Policy allow { # Users can access their own salary input.user == input.path[2] } allow { # HR can access any salary user := data.users[input.user] user.department == "hr" } Input
  • 44. openpolicyagent.org Summary Lookup values input.path[1] Compare values "bob" == input.user Assign values user := input.user Rules <head> { <body> } Rule Head <name> = <value> { … } or <name> { … } Rule Body <statement-1>; <statement-2>; … (ANDed) Multiple Rules with same name <rule-1> OR <rule-2> OR ... Default Rule Value default <name> = <value> Functions Rules with arguments Context Reference with data. instead of input.
  • 45. Agenda ● How Policies are Invoked ● Simple Policies ● Policies with Iteration ● Additional Topics ○ Modularity ○ Negation ○ Any/All ○ Non-boolean Decisions
  • 46. Policies With Iteration ● Iteration ● Virtual documents ● Virtual documents vs Functions
  • 47. openpolicyagent.org { "resources": [ {"id": "54cf10", "owner": "alice"}, {"id": "3df429": "owner": "bob"} ... ], ... } # allow if resource is at element 0 allow { input.resource == data.resources[0].id input.user == data.resources[0].owner } What about Arrays? Allow if user owns resource. Not sure where resource is in array { "user": "alice" "resource": "54cf10", } Input Data
  • 48. openpolicyagent.org { "resources": [ {"id": "54cf10", "owner": "alice"}, {"id": "3df429": "owner": "bob"} ... ], ... } # allow if resource is at element 0 allow { input.resource == data.resources[0].id input.user == data.resources[0].owner } # OR if resource is at element 1 allow { input.resource == data.resources[1].id input.user == data.resources[1].owner } What about Arrays? Allow if user owns resource. Not sure where resource is in array { "user": "alice" "resource": "54cf10", } Input Data
  • 49. openpolicyagent.org { "resources": [ {"id": "54cf10", "owner": "alice"}, {"id": "3df429": "owner": "bob"} ... ], ... } # allow if resource is at element 0 allow { input.resource == data.resources[0].id input.user == data.resources[0].owner } # OR if resource is at element 1 allow { input.resource == data.resources[1].id input.user == data.resources[1].owner } ... What about Arrays? Allow if user owns resource. Not sure where resource is in array { "user": "alice" "resource": "54cf10", } Input Data Problem: Unknown number of elements. Cannot write allow for every index.
  • 50. openpolicyagent.org { "resources": [ {"id": "54cf10", "owner": "alice"}, {"id": "3df429": "owner": "bob"} ... ], ... } # allow if resource is anywhere in array allow { input.resource == data.resources[index].id input.user == data.resources[index].owner } Iterate over Arrays Allow if user owns resource. Not sure where resource is in array { "user": "alice" "resource": "54cf10", } Input Data
  • 51. openpolicyagent.org { "resources": [ {"id": "54cf10", "owner": "alice"}, {"id": "3df429": "owner": "bob"} ... ], ... } # allow if resource is anywhere in array allow { input.resource == data.resources[index].id input.user == data.resources[index].owner } Iterate over Arrays Allow if user owns resource. Not sure where resource is in array { "user": "alice" "resource": "54cf10", } Input Data Solution: ● allow is true if SOME value for index makes the rule body true. ● OPA automatically iterates over values for index. ● allow is true for index = 0
  • 52. openpolicyagent.org Iterate over Everything Iterate over arrays/dictionaries (whether input or data) # Iterate over array indexes/values resource_obj := data.resources[index] # Iterate over dictionary key/values user_obj := data.users[name] # Doesn’t matter whether input or data value := input[key] # Use _ to ignore variable name # Iterate over just the array values resource_obj := data.resources[_] { "method": "GET", "path": ["resources", "54cf10"], "user": "bob" } Input { "resources": [ {"id": "54cf10", "owner": "alice"}, {"id": "3df429": "owner": "bob"} ], "users": { "alice": {"admin": false}, "bob": {"admin": true}, "charlie": {"admin": true}, } } Data
  • 53. openpolicyagent.org Duplicated Logic Happens with Iteration too { “users”: [ {"name": "alice", "admin": false, “dept”: “eng”}, {"name": "bob", "admin": true, “dept”: “hr”}, {"name": "charlie", "admin": true, “dept”: “eng”}, } } Data allow { user := data.users[_] user.admin == true user.name == input.user input.method == “GET” } allow { user := data.users[_] user.admin == true user.name == input.user input.method == “POST” } Duplicated logic with iteration
  • 54. openpolicyagent.org Duplicated Logic Happens with Iteration too { “users”: [ {"name": "alice", "admin": false, “dept”: “eng”}, {"name": "bob", "admin": true, “dept”: “hr”}, {"name": "charlie", "admin": true, “dept”: “eng”}, } } Data allow { user := data.users[_] user.admin == true user.name == input.user input.method == “GET” } allow { user := data.users[_] user.admin == true user.name == input.user input.method == “POST” } Duplicated logic with iteration Avoid duplicating common logic like a search for admins
  • 55. openpolicyagent.org Create a Virtual Document { “users”: [ {"name": "alice", "admin": false, “dept”: “eng”}, {"name": "bob", "admin": true, “dept”: “hr”}, {"name": "charlie", "admin": true, “dept”: “eng”}, } } Data allow { admin[input.user] input.method == “GET” } allow { admin[input.user] input.method == “POST” } admin[user.name] { user := data.users[_] user.admin == true } Duplicated logic with iteration admin is a set that contains all of the admin names Sets are an extension of JSON. admin == { "bob", "charlie" }
  • 56. openpolicyagent.org Different Syntaxes for Virtual Sets { “users”: [ {"name": "alice", "admin": false, “dept”: “eng”}, {"name": "bob", "admin": true, “dept”: “hr”}, {"name": "charlie", "admin": true, “dept”: “eng”}, } } admin[user.name] { user := data.users[_] user.admin == true } Data Rule Syntax admin = {user.name | user := data.users[_] user.admin == true } Set Comprehension Syntax
  • 57. openpolicyagent.org Different Syntaxes for Virtual Sets { “users”: [ {"name": "alice", "admin": false, “dept”: “eng”}, {"name": "bob", "admin": true, “dept”: “hr”}, {"name": "charlie", "admin": true, “dept”: “eng”}, } } admin[user.name] { user := data.users[_] user.admin == true } Data Rule Syntax admin = {user.name | user := data.users[_] user.admin == true } Set Comprehension Syntax Supports OR with multiple rules. No support for OR.
  • 58. openpolicyagent.org Create Virtual Dictionaries too { “users”: [ {"name": "alice", "admin": false, “dept”: “eng”}, {"name": "bob", "admin": true, “dept”: “hr”}, {"name": "charlie", "admin": true, “dept”: “eng”}, } } Data admin[user.name] = user.dept { user := data.users[_] user.admin == true } Rule Syntax admin = {user.name: user.dept | user := data.users[_] user.admin == true } Dictionary Comprehension Syntax
  • 59. openpolicyagent.org Virtual Docs support iteration. Functions don’t. admin[user_name] = user.dept { user := data.users[_] user.admin == true user.name == user_name } admin(user_name) = user.dept { user := data.users[_] user.admin == true user.name == user_name } Dictionary Function # lookup bob’s department admin[“bob”] # iterate over all user/dept pairs admin[user] = department # iterate over everyone in HR admin[user] == “hr” # lookup bob’s department admin(“bob”) # iterate over all user/dept pairs Can’t. Write different function. # iterate over everyone in HR Can’t.
  • 60. openpolicyagent.org Virtual Documents must be finite. Functions don’t. Can’t express split_path. Virtual docs must be “safe”. Safety means the set of all input/output pairs is finite. split_path takes any string as input. There are infinitely strings. split_path(str) = parts { trimmed := trim(str, "/") parts := split(trimmed, "/") } Virtual Doc Function
  • 61. Agenda ● How Policies are Invoked ● Simple Policies ● Policies with Iteration ● Additional Topics ○ Modularity ○ Negation ○ Any/All ○ Non-boolean Decisions
  • 62. openpolicyagent.org People can Create Multiple Policies and Delegate package http.service_graph allow { input.source == “frontend” input.destination == “finance” } ... Service graph policy package http.org_chart allow { admin[user.input] } ... Organization chart policy package http.authz import data.http.service_graph import data.http.org_chart allow { org_chart.allow service_graph.allow } Entry point policy
  • 63. openpolicyagent.org Policies can use Negation package http.service_graph deny { input.source == “frontend” input.destination == “finance” } ... Service graph policy package http.org_chart allow { admin[user.input] } Organization chart policy package http.authz import data.http.service_graph import data.http.org_chart allow { org_chart.allow not service_graph.deny not deny } deny { ... } Entry point policy
  • 64. openpolicyagent.org { “users”: { "alice": {"admin": false, “org_code”: “11”}, "bob": {"admin": true, “org_code”: “22”}, "charlie": {"admin": true, “org_code”: “33”} } } Any vs. All Data Check if all users are admins. Wrong ans: all_admins = true { data.users[user_name].admin == true }
  • 65. openpolicyagent.org { “users”: { "alice": {"admin": false, “org_code”: “11”}, "bob": {"admin": true, “org_code”: “22”}, "charlie": {"admin": true, “org_code”: “33”} } } Any vs. All Data Check if all users are admins. Wrong ans: all_admins = true { data.users[user_name].admin == true } Problem: all_admins is true if ANY users are admins.
  • 66. openpolicyagent.org { “users”: { "alice": {"admin": false, “org_code”: “11”}, "bob": {"admin": true, “org_code”: “22”}, "charlie": {"admin": true, “org_code”: “33”} } } Any vs. All Data Check if all users are admins. all_admins = true { not any_non_admins } any_non_admins = true { user := data.users[user_name] not user.admin } Solution: 1. Check if any users are NOT admins 2. Complement (1)
  • 67. openpolicyagent.org { “users”: { "alice": {"admin": false, “org_code”: “11”}, "bob": {"admin": true, “org_code”: “22”}, "charlie": {"admin": true, “org_code”: “33”} } } Any vs. All Data Check if all users are admins. all_admins = true { not any_non_admins } any_non_admins = true { user := data.users[user_name] not user.admin } Solution: 1. Check if any users are NOT admins 2. Complement (1)
  • 68. openpolicyagent.org allow/deny are NOT special. Decisions are JSON DataLogic POST v1/data/http/authz/admin {"input": { "method": "GET", "path": ["finance", "salary", "alice"], "user": "bob"}} 2. Example Policy 1. Example Request 3. Example Response {“result”: [“bob”, “charlie”]} package http.authz import data.http.service_graph import data.http.org_chart admin[x] { org_chart.admin[x] } admin[x] { service_graph.admin[x] } Sets defined with multiple rules are unioned together. Policy decision can be any JSON data: boolean, number, string, null, array, or dictionary. Sets are serialized to JSON arrays.
  • 71. openpolicyagent.org Policies Iterate to Search for Data { “users”: { "alice": {"admin": false, “org_code”: “11”}, "bob": {"admin": true, “org_code”: “22”}, "charlie": {"admin": true, “org_code”: “33”} }, “orgs”: { “00”: {“name”: “HR”}, “11”: {“name”: “Legal”}, “22”: {“name”: “Research”}, “33”: {“name”: “IT”}, “44”: {“name”: “Accounting”}, } } Data Search for the data you need user_obj user_name org_name {"admin": true, ...} bob Research {"admin": true, ...} charlie IT # Find admin users and their organization user_obj := data.users[user_name]; user_obj.admin == true; org_name := data.orgs[user_obj.org_code].name Variable assignments that satisfy search criteria
  • 72. openpolicyagent.org Policies Give Names to Search Results Data Name the search results admins[[org_name, user_name]] { user_obj := data.users[user_name] user_obj.admin == true org_name := data.orgs[user_obj.org_code].name } { “users”: { "alice": {"admin": false, “org_code”: “11”}, "bob": {"admin": true, “org_code”: “22”}, "charlie": {"admin": true, “org_code”: “33”} }, “orgs”: { “00”: {“name”: “HR”}, “11”: {“name”: “Legal”}, “22”: {“name”: “Research”}, “33”: {“name”: “IT”}, “44”: {“name”: “Accounting”}, } } admins is a set that contains all of the [org_name, user_name] pairs that make the body true. admins == { ["Research", "bob"], ["IT", "charlie"], }
  • 73. openpolicyagent.org Policies Apply Search Results to Make Decisions Input { “users”: { "alice": {"admin": false, “org_code”: “11”}, "bob": {"admin": true, “org_code”: “22”}, "charlie": {"admin": true, “org_code”: “33”} }, “orgs”: { “00”: {“name”: “HR”}, “11”: {“name”: “Legal”}, “22”: {“name”: “Research”}, ... Apply the search results allow { # allow admins to do everything admins[[_, input.user]] } admins[[org_name, user_name]] { user_obj := data.users[user_name] user_obj.admin == true org_name := data.orgs[user_obj.org_code].name } Check if bob is an admin Lookup IT admins Iterate over all pairs admins[[_, “bob”]] admins[[“IT”, name]] admins[x] { "method": "GET", "path": ["resources", "54cf10"], "user": "bob" } Data