1

我正在创建一个策略来验证对记录集合的访问。这些记录作为输入传递,并附加了一组权限。我根据存储在 OPA 中的权限数据验证它们。

例如,我可以通过执行以下操作返回可访问的记录集合

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" }

哪个会返回类似

"isAllowed": ["123"]

当输入如下并且“权限”数据包含“service.legal.user”时

  "input": { 
        "operation": "update", 
        "records": [
            { "id": "123", "acls": { "owners": ["service.legal.user"] }},
            { "id": "456", "acls": { "owners": ["service.storage.viewer"] }}
        ]
   }

但是,我想返回类似以下内容的内容,其中列出了所有输入记录,并将错误消息分配给那些因所有失败原因而失败的记录

"records":[
   {"id": "123", "errors": ""}, 
   {"id": "456", "errors": "You must have owner permission to update a record"}
]

我尝试了增量规则,但我从 OPA 收到错误消息“完整规则不得产生多个输出”

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"
}

欢迎任何帮助。

4

1 回答 1

0

不确定我是否完全遵循,并且您没有提供权限对象,但假设groups只是{"name": "service.legal.user"} 像下面这样的对象列表会产生您想要的输出。

records[response] {    
    id := input.records[_].id
    errors := [r | e := check_errors[_]
                   e.id == id
                   r := e.reason]
    
    response := {
        "id" : id,
        "errors" : errors
    }
}

check_errors[{"id": id, "reason": "Must be an owner to update a record"}] {
    input.operation == "update"
    id := input.records[x].id
    permissionSet := {x | x := permissions.groups[_].name}
    owners := {o | o := input.records[x].acls.owners[_]}
    
    count(owners & permissionSet) == 0
}

完整的例子在这里

于 2021-12-14T13:40:28.863 回答