spicedb
spicedb copied to clipboard
Support for `this` to allow checks on resources with themselves as the subject
There are some certain scenarios where we want to check a subject against itself as the resource, for example:
definition user {
relation manager: user
permission view_paystubs = manager + <the user themselves>
}
We would want to have checks for this pass:
check(user:user_id, view_paystubs, user:user_id)
We should discuss adding some kind of keyword to the schema language which allows a permission to refer to the subject itself without an explicit relationship.
As a workaround, for now, we can write an extra relationship between a resource and itself.
definition user {
relation manager: user
relation myself: user
permission view_paystubs = manager + myself
}
user:user_id#myself@user:user_id
(Very rough) outline of tasks if this were to be added:
- [x] Determine keyword to use.
- [x] Ensure the keyword is not being used in any relation, type or permission names
- [x] Add keyword to schema on backend
- [x] Add keyword to schema on frontend
- [x] Add support for new construct in https://buf.build/authzed/api/docs/main/authzed.api.v0#authzed.api.v0.SetOperation.Child (NOTE: the existing
_thisis something different) - [x] Add dispatcher support for the new construct
- [x] Add consistency tests for the new construct
My project would also benefit from a subject being able to check itself.
I have an organization and a user definition in my model, and I need to model an edit permission on a user. The only people that should be allowed to edit a user's profile are:
- The user themself
- An administrator.
To do this, I've added a self relation on user which I need to keep up to date in my application, but if spicedb had a built-in relation for this that would be more elegant.
Here's the relevant part of my schema that I use to achieve this right now:
definition user {
relation self: user
relation viewer: user
relation organization: organization
permission edit = self + organization->create_user
permission view = viewer + edit + organization->member
}
definition organization {
relation admin: user
relation direct_member: user
permission member = admin + direct_member
permission create_user = admin
}
Regarding the name for the built-in relation, I'd prefer something that starts with an underscore to avoid potential collisions with existing schemas. My first choice would be _self, but I'm flexible.
BTW, you're all doing amazing work on authzed. It's come so far since I first discovered it. Thank you! :slightly_smiling_face:
EDIT: I actually think the modified proposal below is a bad idea now, since you lose the semantics of a user editing themselves, and it just makes the permission wide open. Leaving this here for discussion's sake.
It occurs to me that we might want to have self or this always refer to the subject of the top level request. That way you could to things like:
definitions org {
relation admin: user
permission remove_admin: admin - self
}
A an admin can remove any admin except themselves.
I can't come up with a use case where we would want access to the org object instead, since the subjects for other branches are all going to boil down to something that's likely not an org.
Any update on whether or not this will be supported? It would be nice to use a this or self in the following example:
definition user {
permission user_can_view_some_private_info = this // "this" could be replaced with "self" or something that points back to the user doc
}
Voting on potential names:
thisself- Something else: please offer a suggestion
1️⃣ (this)
Also an interesting read, if you are looking for any deeper meaning behind the choice - https://en.wikipedia.org/wiki/This_%28computer_programming%29
I vote for self, seems more intuitive as we talking about users rather then things.
PR for self keyword: https://github.com/authzed/spicedb/pull/1511
This is now supported in HEAD as a direct keyword in permission. It is not supported as a synthetic relation on either relation or use for arrows. If that is desirable behavior, please file a followup issue and we'll address.
Supported:
permission view = viewer + self
Unsupported:
relation viewer: self#somerel
relation viewer: user#self
permission view = self->something
reopening this as we reverted the change until we come up with a way to facilitate the roll out
https://github.com/authzed/spicedb/pull/1515
Throwing ideas out there (probably already considered) to hopefully support progress on this:
- Allow overloading reserved identifier. ie if
selfis defined as a relation,selfin permissions should refer to this relation rather than the identifier.- Nice for backward compatibilty, adds complexity to the language. Potentially a footgun.
- Use a reserved grammar for built-in identifier, eg
$selfwhere$isn't allowed in user-defined identifiers.- It does complexify the language grammar.
- Make it a breaking change, leave it to users to deal with.
- Not very friendly, wouldn't support this idea
Other options currently being considered:
- If
selfis used as a relation, keep supporting that. Otherwise, parse using the newer parser and fallback as necessary - Add a
version whatever;at the top of schema for new versions - Add a
version 1.0;at the top of schema for old versions
My personal opinion is #1, but it won't be "obvious"
Schema versions or "features/imports" sound better to me than having no full reverse compatibility with future server versions.