-
Notifications
You must be signed in to change notification settings - Fork 284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Allow any relation to provide parameter values for caveats #1528
Comments
Here's an example that motivates need for this feature - Background: In the system, admin users can create Policies that define the permissions granted to users over resources. Each policy declares constraints that limit when the policy applies. Some example constraints (of which there are many) are: if the current user is in the same organisation as the resource; if the current user is the manager of the resource; if the current user is the task assignee of the resource, and so on. The policies will slowly change over time, as does the organisation hierarchy and sets of users. I've already reimplemented much of the existing system in SpiceDB, taking an approach inspired by the 'Google IAM' example in the playground. Here's a simplified schema in terms of just a single permission 'read' and the three constraints mentioned above -
The main thing to note is that a resource delegates to policy_bindings for permission calculation - and the policy bindings call back into one of the constraints on the resource itself. That is, assuming a policy p1 that is constrained to managers, and a policy p2 that is constrained to taskAssignees. Then, for a resource r1 , the following relationships from the resource to policy bindings and back again are written -
And this seems to work well. (although the policy_bindings need to be redone for all resources when a policy is changed) The Problem, Policies can be constrained to only apply to users who are assigned to a role. Unfortunately this can't be implemented the same way as the constraints above, because roles themselves are dynamic - so there isn't a fixed I've tried, unsuccessfully, to solve this using a caveat, adding the following definitions to the above schema -
To represent a role assignment, a relationship is written with a partially-bound role caveat where the actual_role is provided -
However, this doesn't work, because missing caveat parameters can only be provided in the CheckPermissionContext - and in this case, it's the In fact, there may be multiple policy_bindings involved in a single permission check, each of which would supply a different value for the |
I think it would be useful if this actually wasn't limited to relations providing that context. If you have multiple paths to an object, it means you would need to ensure all of those provide the necessary context attributes. For example...
If read was conditional on attributes of the document, and you wanted to have those provided by spicedb rather than the user (e.g. to support resource-related caveats on LookupResources), you'd have to ensure all of the folder and label relations provided that context. If we could attach those attributes to the document itself, maybe that problem goes away. (I suppose you could possibly work around it by defining a sort of superfluous "container" type for the document, provide the folder/label relations there, so that for the actual document object there was only ever one path to it, at the cost of making the management of tuples more complicated.) In our case, I think the policy we're trying to model doesn't strictly require this, it just might make migration a lot easier because it might allow something closer to a direct translation from the existing system. |
I was looking for exactly this support and ended up here. It would be very useful if relations could supply parameters to be added to the context when traversed and have this accumulated context be used in caveats. My two cents, thanks. Very impressed with SpiceDb. Thanks. |
Problem Statement
Caveats allow a relationship to be defined conditionally - a caveated relationship is only considered to be present if the caveat function evaluates to true.
When writing a caveated relationship, values can be supplied - these are provided as parameters to the caveat function at runtime, and allow for a partial binding of data.
The remaining parameters required by a caveat function are taken from the values provided by the CheckPermissionRequest.
Providing the remaining parameters only from the request limits the usefulness of caveats as a language feature.
In particular, the value of each parameter is constant for the whole request - it is not possible to provide different values for a parameter for different branches of a permission-check walk through the graph.
Solution Brainstorm
Behaviour
When writing any relationship, allow a context of values to be provided.
These values would be in scope for walks that traverse the relation - and provided as parameters to caveats encountered on the walk.
Precedence
Values provided by a relationship would take precedence over values with the same name provided by previously-encountered relations or the CheckPermissionRequest.
In turn, the values would be masked by values with the same name in subsequent relationships - including values provided in a caveated relationship.
Schema
Optionally, the schema language could be extended to indicate that a relation allows values to be provided -
Or, perhaps the schema language should be more precise and enumerate the values that must be provided -
Although this is clearer, it may be too prescriptive, and is asymmetric to how caveated relations are currently described (where the parameters required to be partially-bound are unspecified) -
Perhaps the parameter values to be partially-bound could be specified here too -
Or may be simpler to stick with a more relaxed treatment of values in the schema.
The text was updated successfully, but these errors were encountered: