self-relations for GCP IAM
# spicedb
a
Unrelated question, I see the GCP IAM example was rewritten to "use self relations instead of wildcards" – why is this? ([diff](https://github.com/authzed/examples/commit/cc64cb5012bc26543c09d74ab8df25943f82dc57)). We are using a similar pattern and I could update now without a big migration problem... wondering if I should 🙂 ... Edit: On closer inspection it looks like this is a little too different for us to update, but curious anyway in case there was some issue with the prior model
e
the short answer is that it should perform better and provide very similar semantics for the application
it requires fewer relationships to model the same idea
a
It looks like you'd have to define a role per set of permissions and user, though?
e
no, you define a role once and then bind specific users to it
you can have multiple
bound_user
rels
a
So for example if there is a DB admin role, but I want to give it to user A on project1, but to user B on project 2, if I'm reading this right I would need a different role? Because the same role would give both users access to both projects?
e
(brb)
you're right that roles get bound to specific resources, and you would have to copy the permission bindings if you wanted to bind different users to different databases with the same permissions. Depending on your use-case that might be fine; for example it might mean that every project gets to decide what "admin" permission really means and there's no global "database admin" definition. sometimes standardizing the definitions is less important too because most bindings can happen at a higher level - i.e. you might actually bind permissions to a parent
project
object, and only make bespoke per-database roles for serviceaccounts (which tend to be one-offs that you make as minimally permissive as possible). but if you need it, you can add that back in a few ways. the most flexible would be to require both a role and a user grant, so you say like:
Copy code
definition database {
    relation granted: role
    relation granted_user: user

    permission get_operation = granted_user & granted->can_spanner_databaseoperations_get
}
or, if you have standard role template definitions, you could encode them directly in the schema, i.e.:
Copy code
definition database {
    relation granted: role
    relation admin: user

    permission get_operation = admin + granted->can_spanner_databaseoperations_get
}
which would let you change the global definition of admin via schema changes instead of data changes, but still allow custom roles when needed.
a
That's interesting...
Did you find the prior pattern performed particularly badly? Or any specific issues?
We had load tested it pretty heavily, but not yet seen real production usage
y
a big part of why we came up with that iteration is that Materialize doesn't support wildcards (yet), which would be a prerequisite for the old GCP schema
but beyond that, intersections can perform worse because they require the system to be aware of the entire set of relations on both sides of the
&
in order to say whether their intersection is nonempty
whereas a purely arrow-based implementation can potentially short-circuit
it wasn't born of a specific issue that we saw, however
and at my old company we did just fine with an old-style schema and ~100k resources on relatively minimal infra (fully understanding that 100k is kinda tiny)
7 Views