I am creating a policy to validate access to a collection of Records. These records are passed as input and have a collection of permissions attached to them. I validate them against permissions data stored in the OPA.
For instance, I can return the collection of Records that are accessible by doing something like this
isAllowed[id] {
permissionSet := {x | x := permissions.groups[_].name}
id := input.records[i].id
input.operation == "update"
input.records[i].acls.owners[j]==permissionSet[k]
}{
id := input.records[i].id
input.operation == "create" }
Which would return something like
"isAllowed": ["123"]
when the input is like the following and the 'permissions' data included "service.legal.user"
"input": {
"operation": "update",
"records": [
{ "id": "123", "acls": { "owners": ["service.legal.user"] }},
{ "id": "456", "acls": { "owners": ["service.storage.viewer"] }}
]
}
However I want to return something like the following where I list all input records and assign error messages to ones that have failed with all the reasons it failed
"records":[
{"id": "123", "errors": ""},
{"id": "456", "errors": "You must have owner permission to update a record"}
]
I have tried an incremental rule but I get the error message from OPA 'complete rules must not produce multiple outputs'
isAllowed = response {
#owner permission checked for update operation on all records
some i
response := {
"id" : input.records[i].id,
"errors" : CheckErrors
}
}
CheckErrors[reason] {
reason := "Must be an owner to update a record"
input.operation == "update"
permissionSet := {x | x := permissions.groups[_].name}
input.records[i].acls.owners[j]==permissionSet[k]
}
CheckErrors[reason]{
#no permission checked for create operation on all records
reason := "Anyone can create"
input.operation == "create"
}
Any help would be welcome.