-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Quite possibly there's a way to do what I want, but haven't been able to figure it out. I'm gating access to some object, based on data in that object. Normally the policy just checks for simple ownership:
Authority:
user(1234);
Authorizer:
check if user({content_owner});
// or equivalently, where the content_owner() fact is injected based on the object contents
content_owner({content_owner});
check if user($u), content_owner($u);
However, sometimes there's an extra field on the content (say, a group) and the user needs to also be a member of that if present. So you could write the authorizer like:
check if
user({content_owner}),
user_group({content_group});
I could dynamically add the check depending on the object properties, but if I'm going to have some random code doing that I might as well just check it directly; my hope is that the authorizer is static and the source of truth for the rules. There are a lot of different cases here and I was hoping to have a single Authorizer file for each.
So, I'm struggling to write policies that can selectively depend on certain facts. Conceptually what I want is something like:
check if no_fact_exists(object_group($oid, $_)) or object_group($oid, $gid), user_group($gid);
Or, some way to construct a set out of all the terms in a fact, where "no match" results in an empty set.
The best solution I've found so far is to make the injected fact carry a set, ab empty set indicates a null/missing value, and this fact is always added to the Authorizer e.g:
object_group(..., []); // object has no required groups
object_group(..., [1234]); // object does require groups
check if
object_group($oid, $groups), user_groups($user_groups),
$object_groups == $user_groups || $object_groups.intersect($user_groups).length() > 0;
Any thoughts?