likely the caveats feature
# spicedb
y
likely the caveats feature
i
Hi @yetitwo , thanks. I had looked at the caveats feature, but that seemed to be intended more for conditional relationships, than actually passing in brand new relations. Do you have an example you might be able to share? I found this article, but it's not quite what we need: https://authzed.com/blog/top-three-caveat-use-cases
y
it wouldn't be represented as a temporary relation - you'd need to rephrase your request in terms of the caveats feature
in spicedb, if you have request-time information that you want to provide, you do it with caveats
i
Ok. I'll try to think through how that could work. At first glance, it seems like we'd need to duplicate our auth logic, one eval path for users managed via relations on groups in SpiceDB, and another evaluation path (probably with the union "|" operator) that says if their context has a specific group?
y
i'm not sure off the top of my head - caveats are one feature i haven't dug into
j
if a user has access without condition, writing them directly
if they have conditional access, write the relationship with a caveat
i
Hi Joey, can you explain more? As I understand it, the user's access would not be conditional, they would be a part of their groups present in their token. The difference is I just need to pass in those relationships during the evaluation, since my application won't know about them before receiving the token
j
does the token say they are part of a group or is it something other indication?
i
Yeah, generally with some of the enterprise IDP's we integrate with, they have a claim in the token that is similar to:
Copy code
"groups": ["group1", "group2"]
So generally, it says they are members of a group or role
j
and how would these groups impact the authz decisions?
how do they link over?
i
They would correspond to a
member
relation on a
group
resource in our authorization model. Then permissions would be determined from the groups relation with other resources. You could think of it as well in terms of roles, the claims in the token would represent the roles that have been assigned to the user from the external IDP, so those roles would then have relations with other objects.
j
right, but to... what? if the membership of the groups is not contained in SpiceDB, what are you linking to? is it the resource->group?
i
I'm not sure I understand your question but let me give an example to see: One of our resources is a
project
, and project would have a relation
owner: group#member
, and permissions would apply to the project resouce based on the members of the
owner
group.
j
okay, so it is resource->group
i
Yup, it would be resource->group, then group->user, but the group->user comes from the IdP's token. OpenFGA supports this by passing in evaluation-time relationships that are not persisted in the relationship DB. I'm trying to understand what might be a way in SpiceDB to support this workflow
j
you'd write a caveat on the member to
user:*
and check the group ID
like
Copy code
caveat has_matching_group_id(group_id string, users_group_ids list<string>) {
  users_group_ids.contains(group_id)
}

definition group {
  relation member: user:* with has_matching_group_id
}
then write a relationship
group:whatever#member@user:*[has_matching_group_id:{"group_id": "whatever"}]
something like that
eval-time relationships are "easier", but they would have a negative caching impact
we've been investigating what it would look like to support it without destroying caching
but nothing concrete on that yet
i
Ok I think I'm understanding now. So this effectively says "make any user a member of group whatever, but only those that have a matching group ID in their context at eval time can use the relationship"?
j
basically
you could also just not have the
group
itself
and instead do
Copy code
caveat has_matching_group_id(allowed_group_ids list<string>, users_group_ids list<string>) {
  // ensure the groups have crossover
}

definition project {
  relation viewer: user:* with has_matching_group_id
}
err, sorry;
project
I forget the exact function name for intersection of lists
that would likely be more efficient, if a bit less nice to manage
i
Ok that makes sense. Thank you very much for the examples Joey!
Hey @Joey , reviving this old thread on conditional group membership / evaluation time relations because I'm now implementing it for a customer of ours. Unforatuntely I'm hitting an issue with your suggestion. I get the following error with my schema:
Copy code
for relation `user`: relation/permission `group#member` includes wildcard type `user` via relation `group#member`: wildcard relations cannot be transitively included(group#member)
I've created this playground example with a minimal reproducable example. Do you have any ideas how I might be able to fix this? Unfortunately we've built most of our authz system assuming this would work, but now are running into an issue on this last feature. Thanks for the help! https://play.authzed.com/s/Ga68wFUVbt3k/schema
also @yetitwo not sure if you may have any thoughts?
if it helps, we're very closely following the example from the "Modeling Google Cloud IAM in SpiceDB" blog post: https://authzed.com/blog/google-cloud-iam-modeling
y
you can arrow to a relation that contains a wildcard; you just can't hash to it.
so
role_binding
could have both
relation user: user
and
relation group: group
and then the permission would be
(user + group->member)
i
y
yep
and you can use parens if you don't want to write out the intersection twice
role->project_read & (user + group->member)
i
Awesome, thank you for the suggestion! I'm guessing that means we'll have to migrate all the relations already in the db that are written to
group#member
?
y
yep, yeah
i
bummer ok, thanks
y
yeah :/ it'll be a four-phase migration: write a schema with the new
group
relation used in addition to the
user
relation, do a data/code migration to copy the relations over and stop writing the old relation, clean out the old relation, and then write a new schema that gets rid of the old relation
i
thanks for the tips.. we've had to do a few of these now. If I can make a feature request - it would be cool if spiceDB could provide some sort of migration capability to make these less painful
y
i like the idea, but i'm not entirely sure how it would work... the process is roughly analogous to renaming a column in postgres without downtime, which also requires a four-phase migration, because you're having to coordinate between the calling codebase and the datastore. did you have an idea in mind?
i
yeah i'm not entirely sure either.. i think it might be more client side than the server side, like some framework similar to Alembic or other migration managers that would let us manage spiceDB schemas like we do SQL schema evolutions. Something that keeps a versioned history of the changes, and can carry the logical burden of tracking what version of the schema the instance is on, and running the scripts to bring it up to date, etc. Just thinking something to codify the best practices of how to properly manage this stuff so everyone isn't writing one-off implementations
y
ah, yeah, that makes sense. it'd work best in a system where the calling code and the schema + configuration of the SpiceDB instances were held in the same codebase, but it would definitely be a smoother experience. i'll chew on that.
i
Sure thing, always happy to provide thoughts if you have more questions. Thanks for the help!
y
sure thing!
98 Views