-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Hello,
I am having trouble implementing the get_query method for sql_alchemy in our app. Here's what I've got going on. I am fairly new to Cerbos so it may (likely??) be that something is wrong on my end, but I'm a bit stumped so I'm asking for help.
Simplified policies are as follows:
Policies
# org policy
---
apiVersion: api.cerbos.dev/v1
resourcePolicy:
resource: org
version: default
importDerivedRoles:
- common_roles
rules:
effect: EFFECT_ALLOW
- actions: ['org.read']
derived_roles: [
'OrgViewer',
]
# derived role
- name: OrgViewer
parentRoles: ['user']
condition:
match:
any:
of:
- expr: P.attr.orgs[R.id].role == "owner"
- expr: P.attr.orgs[R.attr.org_id].role == "owner"
- expr: P.attr.orgs[R.id].role == "viewer"
- expr: P.attr.orgs[R.attr.org_id].role == "viewer"
When I run is_allowed with the following principal and resource, things work as expected and shows that Cerbos is running and knows about the policies.
# principal
{
"id": "user_764c63",
"roles": ["user"],
"attr": {"orgs": {"org_dd60a6": {"role": "owner"}}}
}
# resource
{
"kind": "org",
"id": "org_dd60a6",
"attr": {
"org_id": "org_dd60a6"
}
}
c.is_allowed('org.read', principal, resource) # ---> True
When I try to run get_query with the above principal and the following code, it errors on the get_query line.
plan_resource = PlanResourcesInput.Resource(kind="org")
plan = c.plan_resources("org.read", p, plan_resource)
query = get_query(plan, models.Org, {"request.resource.id": models.Org._id})
The plan looks like this:
Printout of query plan
request_id: "84523808-6920-4e54-bbc7-0ee54d99de6b"
action: "org.read"
resource_kind: "org"
filter {
kind: KIND_CONDITIONAL
condition {
expression {
operator: "or"
operands {
expression {
operator: "eq"
operands {
expression {
operator: "get-field"
operands {
expression {
operator: "index"
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "org_018e5806b4211f0fd2196c1644dd60a6"
}
}
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "role"
}
}
operands {
value {
string_value: "owner"
}
}
}
}
}
}
}
}
}
}
operands {
variable: "request.resource.id"
}
}
}
operands {
variable: "role"
}
}
}
operands {
value {
string_value: "owner"
}
}
}
}
operands {
expression {
operator: "eq"
operands {
expression {
operator: "get-field"
operands {
expression {
operator: "index"
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "org_018e5806b4211f0fd2196c1644dd60a6"
}
}
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "role"
}
}
operands {
value {
string_value: "owner"
}
}
}
}
}
}
}
}
}
}
operands {
variable: "request.resource.attr.org_id"
}
}
}
operands {
variable: "role"
}
}
}
operands {
value {
string_value: "owner"
}
}
}
}
operands {
expression {
operator: "eq"
operands {
expression {
operator: "get-field"
operands {
expression {
operator: "index"
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "org_018e5806b4211f0fd2196c1644dd60a6"
}
}
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "role"
}
}
operands {
value {
string_value: "owner"
}
}
}
}
}
}
}
}
}
}
operands {
variable: "request.resource.id"
}
}
}
operands {
variable: "role"
}
}
}
operands {
value {
string_value: "viewer"
}
}
}
}
operands {
expression {
operator: "eq"
operands {
expression {
operator: "get-field"
operands {
expression {
operator: "index"
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "org_018e5806b4211f0fd2196c1644dd60a6"
}
}
operands {
expression {
operator: "struct"
operands {
expression {
operator: "set-field"
operands {
value {
string_value: "role"
}
}
operands {
value {
string_value: "owner"
}
}
}
}
}
}
}
}
}
}
operands {
variable: "request.resource.attr.org_id"
}
}
}
operands {
variable: "role"
}
}
}
operands {
value {
string_value: "viewer"
}
}
}
}
}
}
}
cerbos_call_id: "01HSC29G47ZD606S6K6MHCVBG6"
The error is
File "/Users/foo/projects/my_project/api/.venv/lib/python3.11/site-packages/cerbos_sqlalchemy/query.py", line 127, in traverse_and_map_operands
variable = d["variable"]
~^^^^^^^^^^^^
KeyError: 'variable'
When I put a print in the file where the error originates, I get this for the value of d:
{'expression': {'operator': 'get-field', 'operands': [{'expression': {'operator': 'index', 'operands': [{'expression': {'operator': 'struct', 'operands': [{'expression': {'operator': 'set-field', 'operands': [{'value': 'org_018e5806b4211f0fd2196c1644dd60a6'}, {'expression': {'operator': 'struct', 'operands': [{'expression': {'operator': 'set-field', 'operands': [{'value': 'role'}, {'value': 'owner'}]}}]}}]}}]}}, {'variable': 'request.resource.id'}]}}, {'variable': 'role'}]}, 'value': 'owner'}
There is no top level variable key in this data structure, which is why it throws an error. I don't really understand why the data structure d is wrong at this point though. Could someone help me out? Thanks!