Hi! Quick schema-question:
# spicedb
c
Hi! Quick schema-question: Given the following snippet:
Copy code
definition page_user_management {
    relation organization: organization:*
    permission can_view = organization->is_admin
}

definition organization {
    relation admin: user
    relation supplier: user
    relation buyer: user
    relation teacher: user
    relation student: user
    relation parent_organization: organization

    permission is_admin = admin + parent_organization->is_admin
    permission is_supplier = supplier + parent_organization->is_supplier
    permission is_buyer = buyer + parent_organization->is_buyer
    permission is_teacher = teacher + parent_organization->is_teacher
    permission is_student = student + parent_organization->is_student

}
What is the convention for "making
page_user_management
public? I guess I would need to create a relation like this:
page_user_management:[some-id] organization organization:*
But what should
[some-id]
be?
v
👋I think I need more information on the business logic, because I can't wrap my head around
relation organization: organization:*
Assuming
page_user_management
was a resource you'd do something like
Copy code
definition page_user_management {
    relation organization: organization
    relation public: user
    permission can_view = organization->is_admin + public
}
but the fact you ask about what the ID of
page_user_management
would be makes me think it's not defined in your app as a resource
it's also odd that all those permisions exist at the organization level without a resource to actually authorize access to. You typically put the permissions in the resource you are protecting
if the resource really is the organization, then you model it following the actions a user can perform over an organization, not the roles they have in that organization
c
You ask good questions. Let me try to explain what I want to achieve: On our platform, we have `User`s who are members of one or more `Organization`s through a
Role
. For example:
organization:my-org admin user:user-1
We also want to model "page permissions" using SpiceDB. The example in my previous message is for a User Management page. For testing purposes, I want all users who have the
admin
role in any organization to have the
can_view
permission on the UserManagement page. Previously, I made a POC where I modeled pages like this:
Copy code
definition page {
    relation viewer: role
    relation excluded_viewer: user
    permission can_view = viewer->member - excluded_viewer
}
However, from my conversations with members of the authzed team, I understood (perhaps incorrectly) that this approach is recommended only for "dynamic pages" or when users can create/delete pages themselves. We have a static set of pages, each with its own set of permissions. Did this make things clearer? Please let me know if you want me to elaborate further - I'd be happy to! Thanks for helping out! I'm really enjoying the learning experience here - it's just a little bit difficult to figure out "the right way" to do things sometimes. 😊
v
Thanks for clarifying. I don't think page permissions is a resource of the organization in this case, or at least it would seem a bit of a stretch because there aren't "multiple user management pages" per organizaztion. What I would do is to model this as a permission in the organization. When your User Management Page loads, what are you granting access to? to manage permissions of an organization. So you would do
check organization:my-org manages_roles user:the_acting_user
when the user management page controller is invoked.
Copy code
definition organization {
    relation admin: user
    relation supplier: user
    relation buyer: user
    relation teacher: user
    relation student: user
    relation parent_organization: organization

    permission is_admin = admin + parent_organization->is_admin
    permission is_supplier = supplier + parent_organization->is_supplier
    permission is_buyer = buyer + parent_organization->is_buyer
    permission is_teacher = teacher + parent_organization->is_teacher
    permission is_student = student + parent_organization->is_student

    permission manages_roles = is_admin
}
please note that an admin will be able to manage roles or their current organization and any children organization
c
Ah, I see where you're going. I will give this way of thinking a try and see how it feels. Currently, we're granting users access to just visit the sites. UserManagement is one of multiple pages that users can access from the menu bar. We issue two queries to SpiceDB: 1.
zed permission lookup-resources page can_view user:user-1
(This is the query from the old POC). This returns a list of all pages the users are allowed to access and is used to populate the menu on the frontend. 2. Whenever a user tries to access a given page using the URL, we check permissions for that page explicitly. In the future, we will add more permissions to each page, and these permissions will differ from each other, hence the schema rewrite now.
Does the additional information in my response change your recommendation?
v
No I don't think it changes my recommendation. The impedance mismatch you found stems from the fact that no resource that exists for a specific page, and the concept of "subject performs action over resource" is central to Zanzibar's design. I can see the appeal of doing a
lookup-resources
to return the tabs to present as allowed to the user, though, but I suspect such a model can have challenges to evolve down the line. It's also not the same as you presented earlier, where the
page_user_management
was modeled in the schema: having a
page
is indeed "dynamic pages" as pointed by fellow Authzedders, since now the page becomes a resource on its own with its own id. The mental model we tend to use when doing SpiceDB schemas is to capture your business logic, defining the main concepts in it, and how they relate to each other (e.g. the GitHub model - organizations have repositories, repositories have issues, users are members of organizations, teams belong to organizations...). The presentation of it (the pages) is a different projection. It's similar to object orientation patterns in away. At the end of the day, whatever works for you is fine. I'm not sure there is anything specific about your application that would benefit from this design, as far as I can tell If I were to design your schema, I'd do a few things: - move away from permissions as roles. describe permissions in terms of the action performed in the application, not on the role the user has. That decouples the privilege grant, from the actual permission the user has. - definitions in your schema are resources of your application. The permissions are "verbs", or actions a subject can perform over a resource - having permission to see a page of an organization should be a permission in the organization if only 1 such page exists (role admin page). - if there are nested resources to the organization (e.g.
/org/<org_id>/nested_resource/<resource_id>
)) then that becomes a definition on its own
As an alternative to doing
lookup-resources
on page load to determine "which tabs to render as enabled / not-greyed out", you can use
BulkCheck
API to check all the permissions you want to render in the UI. (i.e.
check user:covey manage_roles, purchase, supply, teach organization:my-org
)
c
I understand. Thank you so much for you time and thorough answers 🙂 You've given me a lot to think about and work with! 🙂
v
happy to help!
6 Views