spicedb icon indicating copy to clipboard operation
spicedb copied to clipboard

Speculative: Wildcard support for resources

Open josephschorr opened this issue 3 years ago • 9 comments

Originally posted by @bryanaknight in https://github.com/authzed/spicedb/issues/1#issuecomment-973357174

I ran into a use-case (for GitHub) that is related to this.

Scenario: We have specially privileged users (e.g. staff) that have permissions for lots of different objects in our schema. These users and permissions are not tied to any sort of high-level container like an organization.

I asked about this not wanting to have to embed some sort of a "staff" relation into every single object where these users have permission, and the recommendation was

generally, the recommendation in that case is to have some sort of root type, like system or platform connect your items to that, and then place the staff user permission on the root object so say you had resource -> organization you could add resource -> organization -> platform it means attaching every org to the platform, but that should be fairly minimal vs attaching to every resource it also means you can tenant out these kinds of "global" permissions later, if you decide you want a "partially 'global'" staff member

This is working for us but as it states it still means we have a lot of relationships that we need to generate between the organization and any other resource owner(e.g. uesr, business) and the platform. The schema I came up with looks something like:

definition platform {
  relation administrator: user
  permission admin = administrator
}

definition organization {
  relation platform: platform
  permission platform_admin = platform->admin
}

definition repository {
  relation owner: user | organization

  permission delete = owner + owner->platform_admin
}

Not that these platform admins don't have every single permission available on the platform, but they do have a large set of permissions spanning lots of different resource types.

This sparked the idea of utilizing the public type to solve this more efficiently. The current proposal for public is to allow something like resource:someresource#viewer@user:*, which states that any user can view a specific resource. We could theoretically do the inverse of that for this use case resource:*#viewer@user:staffgal, which states that any resource can be viewed (or some other permission) by a specific user.

josephschorr avatar Dec 21 '21 18:12 josephschorr

We have a similar use case where we'd like to assign a relation to all resources of a given type. In our platform we model something similar to AWS Permission Boundaries (permission boundaries specify the policy that governs the maximum level of permissions you can have). In our platform we call these access levels. An access level includes one or more access level permissions.

We have a model like this:

definition workfront/user {
    relation tenant: workfront/tenant

    relation accesslevel: workfront/accesslevel
}

definition workfront/accesslevel {
    relation granted: workfront/user
}

definition workfront/accesslevelpermission {
    relation view_permission: workfront/accesslevel#granted
    relation edit_permission: workfront/accesslevel#granted
    relation manage_permission: workfront/accesslevel#granted

    permission view = view_permission + edit
    permission edit = edit_permission + manage
    permission manage = manage_permission
}

definition workfront/portfolio {
    relation accesslevelpermission: workfront/accesslevelpermission

    relation viewer: workfront/user
    relation editor: workfront/user
    relation manager: workfront/user

    permission view = (viewer + edit) & accesslevelpermission->view
    permission edit = (editor + manage) & accesslevelpermission->edit
    permission manage = manager & accesslevelpermission->manage
}

Every time we write a workfront/portfolio object we have to create the corresponding relationship to the accesslevelpermission. For example,

workfront/accesslevelpermission:portfolio#manage_permission@workfront/accesslevel:planner#granted
workfront/accesslevelpermission:portfolio#edit_permission@workfront/accesslevel:planner#granted

workfront/accesslevel:planner#granted@workfront/user:fred

workfront/portfolio:portfolio1#accesslevelpermission@workfront/accesslevelpermission:portfolio
workfront/portfolio:portfolio2#accesslevelpermission@workfront/accesslevelpermission:portfolio
... etc

It'd be nice if we could just write a single static relationship such as

workfront/portfolio:*#accesslevelpermission@workfront/accesslevelpermission:portfolio

This would eliminate the need to write an additional relationship per object for the association between the object and the access level permissions governing it.

Authzed Playground Link

jonwhitty avatar Mar 01 '22 15:03 jonwhitty

+1 on this from my side as well. We have a use-case where we'd like to effectively do access checks of certain microservices towards one another. For instance, a certain service should have blanket permission on all resources of a certain type when not acting on behalf of a user. We'd basically like to create a new (empty) definition "service", then create a single subject per service, and give each of the services a set of relationships like resource_type_this_service_has_access_to:*#permission_the_service_has@service:some_microservice Since these kinds of checks are pretty easy to implement in custom logic this is not an urgent requirement, but it would be nice to have a single source of truth for all permissions. Doing it in SpiceDB would currently require materializing the set of relationships from each service to each newly created resource, which is not ideal. Anyway, I thought I'd add my 2 cents here.

phdowling avatar Jul 14 '22 21:07 phdowling

+1 as well! We have a lot of resources that do not cleanly fit into a hierarchical structure, so we're being forced to relate each individual resource back to a platform (ie resource:1#platform@my_platform, resource:2#platform@my_platform, ... resource:n#platform@my_platform) even though it feels redundant. Wildcard object IDs in relationship declarations (or even allowing static relations in the resource definitions) would solve this / be greatly appreciated.

kie-ra avatar Sep 16 '22 18:09 kie-ra

+1 for this feature

ysaakpr avatar Jan 13 '23 06:01 ysaakpr

@kindy's static relation proposal offers a very interesting (and powerful) alternative to this idea: https://github.com/authzed/spicedb/issues/1266

josephschorr avatar Apr 20 '23 15:04 josephschorr

+1 for this feature

I think this would be a great feature to reduce the friction for people to adopt SpiceDB. Im explore authZ as a service for our internal services and for the initial prototype/iteration, wildcard resource or static relation would be a great place to start with.

khun84 avatar Oct 29 '23 09:10 khun84

+1 for this feature

karlwang1983 avatar Jan 09 '24 06:01 karlwang1983