spicedb
spicedb copied to clipboard
Proposal: Support defining static relationship in schema
sometimes(like #346), certain resource types are always associated with specific platform instances. Instead of dynamically creating corresponding platform instance relationships for each new resource instance, it is better to define a static relationship in the schema.
In this way, if there is a change of mind later, only the schema needs to be modified, without having to update all the relationships.
This type of static relationship in schema should applicable to both regular resource IDs and *.
definition user { }
definition role {
relation member: user
}
definition sys {
relation admin: user
}
definition sys_a/task {
relation sys: sys
relation role: role
// static relation syntax opt-1
relation static_sys := sys:sys_a | sys:sys_b
relation static_role := role:admin
// static relation syntax opt-2
relation static_sys = sys:sys_a | sys:sys_b
relation static_role = role:admin
permission manage = sys->admin + role_admin->member
}
// static relation exp
sys:*
sys:abc
sys:"+-/ x"
sys:abc#relation
sys:'+-/ x'#relation
We have a root
object in our model, similar to sys
, or platform
. It would be great to have a clean solution to this general use case.
In an ideal world I'd love both this and #346. For the specific problem of the root
level, this proposal might be best as I suspect it would perform better. However, #346 is more flexible and would potentially allow us to remove two levels of depth from our schema, rather than just the 1 a static relationship would afford.
@croemmich how would #346 help remove another nesting level?
Now that I think about it more carefully... it wouldn't. As such, I lean more favorably towards this solution.
@josephschorr In a scenario where I have N different definitions with M permissions each, to be able to grant *
access for each of those N * M permissions, I'd need to define a root definition and define those N * M relations/permissions there and also make permission formulas in all of those N definitions more complex.
When N and M are getting quite large this approach feels less and less appealing.
From this perspective I see #346 as a cleaner approach.
I'd need to define a root definition and define those N * M relations/permissions there and also make permission formulas in all of those N definitions more complex.
Not quite... you could define a static relationship to a parent "universal", such as a pre-defined "platform", and then just hang the subjects off of that:
definition first {
relation platform: 'someplatform'
permission one = platform->admin
permission two = platform->admin
}
definition second {
relation platform: 'someplatform'
permission one = platform->admin
permission two = platform->admin
}
Resource wildcards have a number of major performance and API implications that will almost certainly mean they are not added
Not quite... you could define a static relationship to a parent "universal", such as a pre-defined "platform", and then just hang the subjects off of that:
How would you go about granting Alice wildcard access to perform action one
over any first
resource
and Bob to perform action one
over any second
resource? And nothing else.
Resource wildcards have a number of major performance and API implications that will almost certainly mean they are not added
Joseph, could you please explain those implications in a bit more detail? I'm really curious to understand it better.
How would you go about granting Alice wildcard access to perform action one over any first resource and Bob to perform action one over any second resource? And nothing else.
You'd define a resourcewide
type, add Alice
to the relation for that associated permission, and then check resourcewide:first-type->whatever_permission
. In fact, this would be the recommendation on how to do this today, without any static relationship support
Joseph, could you please explain those implications in a bit more detail? I'm really curious to understand it better.
It has to do with exclusions and lookups. Imagine you have a schema with support for wildcard resources and you define:
definition someresource {
relation viewer: user
relation banned: user
permission view = viewer - banned
}
and then you grant
someresource:*#viewer@user:tom
someresource:specific#banned@user:tom
Now you perform a LookupResources of all resources for which user:tom
can view
: the returned list of resources needs to be * - {specific}
because user:tom
has access to all resources except specific
. This is a problem we encountered after adding wildcard support to subjects and had to engineer around for LookupSubjects
; doing so for LookupResources (and other derivative implementations) would likely become a non-starter, not to mention other performance and design implications