-
-
Save binzram/1d72e265ae7926d1fa5ba7493e2b05a3 to your computer and use it in GitHub Desktop.
# curl -X PUT http://localhost:8181/v1/data/permission -H 'Content-Type: application/json' -d '# Data #' | |
{ | |
"write": [ | |
{ "ressource": [1, 2], "context": null }, | |
{ "ressource": [1, 3], "context": ["foo"] } | |
] | |
} |
# curl -X PUT http://localhost:8181/v1/policies/policies/example.rego -H 'Content-Type: text/plain' -d '# Data #' | |
package opa.example | |
default allow = false | |
allow { | |
input.ressource = data.permission.write[i].ressource[_] | |
input.context = data.permission.write[i].context[_] | |
} | |
allow { | |
input.ressource = data.permission.write[i].ressource[_] | |
is_null(data.permission.write[i].context) | |
} |
# curl -X POST http://localhost:8181/v1/data/opa/example -H 'Content-Type: application/json' -d '# Data #' | |
{ | |
"input": { | |
"ressource": 2, | |
"context": "bar" | |
} | |
} |
Refactored with helper rules
More verbose but avoids duplicating logic inside allow. Policy says that allow is true if permissions_for_resource and perimssions_for_context intersect. This version will only search over the write collection once (whereas in the original version it'll search over it twice.)
allow {
permissions_for_resource[i]
permissions_for_context[i]
}
permissions_for_resource[i] {
data.permission.write[i].resource[_] = input.resource
}
permissions_for_context[i] {
data.permission.write[i].context[_] = null
}
permissions_for_context[i] {
data.permission.write[i].context[_] = input.context
}
Refactored with objects
Using objects instead of arrays. Benefit is that resource permission lookup is constant-time.
allow {
perm := example_perms[input.resource]
perm.any_context
}
allow {
perm := example_perms[input.resource]
perms.context[_] = input.context
}
example_perms = {
"resource1": {
"any_context": true,
"context": ["foo"], # additional context. not required.
},
"resource2": {
"any_context": true,
},
"resource3": {
"context": ["foo"],
},
}
Additional thoughts
In your original version and the first version above the permissions are organized into an array. One challenge with arrays is that OPA has to do a linear scan to find matches. The policy query latency will go up as the size of the array increases. One way to resolve this is to use objects instead of arrays to structure the data. Another way to resolve this is to use OPA's partial evaluation feature on the policy to generate a version that can be evaluated in constant-time: https://blog.openpolicyagent.org/partial-evaluation-162750eaf422.
Rules:
1
withany
context (includingfoo
) is granted2
withany
context is granted3
with contextfoo
is granted4
is denied