-
Notifications
You must be signed in to change notification settings - Fork 190
Description
This might be a bug in the oso library or it might be a problem with the way I am writing authorization rules, but if the latter then I claim that this is because the examples in the oso docs are misleading and have led me to this bad habit. I am constantly running into "unhandled partial" errors that are not the result of the body of a rule but the way multiple rules interact. Here's an minimal example:
resource Group {
permissions = ["query", "update", "delete"];
roles = ["member", "manager"];
relations = { managing_group: Group };
"query" if "member";
"query" if "manager";
"update" if "manager";
"delete" if "manager";
"manager" if "member" on "managing_group";
}
has_role(user: User, "member", group: Group) if
member in group.members and
member matches {id: user.id};
has_relation(parent: Group, "managing_group", child: Group) if
child.managed_by.id = parent.id;
allow(actor, action, resource) if
has_permission(actor, action, resource);
I have problems with the following test:
def test_group_manager_role_rule():
user = User(id=1, ...)
parent_group = Group(id=2, ...)
child_group = Group(id=3, ...)
child_group.managed_by = parent_group
parent_group.members.append(user)
assert oso.query_rule_once(
"has_role", user, "manager", child_group
)This yields the following error:
polar.exceptions.PolarRuntimeError: Found an unhandled partial in the query result: _group_74
[...]
The unhandled partial is for variable _group_74.
The expression is: _group_74 matches Group{} and 2 = _group_74.id and _member_76 in _group_74.members and _member_76.id = 1
It took me a while to get a sense of why oso is doing this, but I've realized it has to do with the fact that in the has_relation rule, the first (left-most) term is a free variable, not a bound one. So it resolves out to a query result which I think should be fully determinate, but oso expects me to have provided, somewhere, an existential assertion ("There is a group such that...") which I have not (and don't know where I would).
Is this a bug in oso or my failure to write a proper ruleset? If the latter, I think that the documentation could be clearer, but to prevent this issue from getting too long, I'll not include my argument now.