Skip to content

Constantly running into "unhandled partial" error #1705

@IohannesArnold

Description

@IohannesArnold

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions