spicedb icon indicating copy to clipboard operation
spicedb copied to clipboard

LookupResources, through object(s)

Open jwineinger opened this issue 1 year ago • 11 comments

I need a way to do a lookup resources request but only select results from a subtree/subset of the user's actual access.

The use case is that a user might be related to many organizations, and might have access to many documents on those many organizations. I want to query for the documents the user has access to, but only for one organization at a time. Getting them all is not necessary, and likely very undesirable from a performance standpoint since there could be a rather large data set for each subtree.

I may want a UI to show the user's access in the context of a single org, or do a authz-aware data export in the context of an org. In either case, I only want/need the one org's data, even though the user legitimately has access to a much wider set of resources of that type (through other orgs).

Sample schema and relationships: https://play.authzed.com/s/xkAf0Jir39ZB/schema

$ zed permission lookup-resources document_type can_read user:user1
org2-invoice
org1-invoice

In this case, I want to be able to query for a single partnership's documents (with respect to the user), so I'd only want to get org2-invoice or org1-invoice at a time, not both.

Semantically, this feels like a request for "LookupResources, through object(s)". Excluding object(s) might be useful, along with analogous operations for LookupSubjects queries, though I don't currently have need for these.

Link to brief discord discussion: https://discord.com/channels/844600078504951838/844600078948630559/1106613923358199931

jwineinger avatar May 12 '23 19:05 jwineinger

@jwineinger in your example, is the filter "comes from the org#member" or is it "the org of the resource is (insert org here)"

josephschorr avatar May 22 '23 21:05 josephschorr

I'm not sure I understand your question exactly, but here's how I visualize the data graph, the lookup-resources call, and what I actually want. As you can see, the user is a member of multiple orgs. Each org has multiple instances of type-z, and the user has the can_read permission to some type-z's on each org. The lookup-resources type-z can_read user:1 call will return them all, but I want a way to only get the results in the green oval.

Note: that the results I want returned won't always be from org-1, it just depends on the context of the operation, and I'd guess that'd need to be specified in the request to SpiceDB. If the user switches context to operate on org-3, then I'd want to be able to query for the type-z's under org-3 instead.

jwineinger avatar May 23 '23 01:05 jwineinger

@jwineinger and what if a resource is under multiple organizations? I assume you still want it returned?

josephschorr avatar May 23 '23 03:05 josephschorr

I don't believe I have that use case. However, I think that is what I would expect; if the object is reachable in the filtered/restricted subgraph, then yes, it should be returned.

jwineinger avatar May 23 '23 14:05 jwineinger

Hi, I have a similar use case, which is even a bit more complicated. I want to filter the "user to folder" relationships by a "folder to folder" permission. More specifically, I want to lookup permitted children (subfolders) of a specific folder. It is actually a combination of two lookup params:

const getReadableFolderIds = async (userId: string) => lookupResources({
    subject: { type: 'user', id: userId },
    permission: 'read_artifacts',
    resourceType: 'folder',
});

const getSubfolderIds = async (parentFolderId: string) => lookupResources({
    subject: { type: 'folder', id: parentFolderId },
    permission: 'is_ancestor',
    resourceType: 'folder',
});

My schema: definition folder { relation direct_child: folder relation parent: folder // The relationship of a folder to all its children, grand children, and so forth. permission is_ancestor = parent + parent->is_ancestor }

I am currently using the two lookupResources commands above and filter the responses. However, it would be nice (and maybe more performant) to make just one call.

Twonky-Chris avatar Jul 27 '23 11:07 Twonky-Chris

@jwineinger Coming back to this after some recent LR work; do you want it to be filtered by a specific resource or a resource+permission (such as organization:org1#view)?

I think with the new experimental LR implementation we could early shear out results that don't reach "through" a resource or a resource+permission; trying to decide which is closer to your requested goal (I think just a resource?)

josephschorr avatar May 20 '24 19:05 josephschorr

From what I know today, resource+permission will fit our use-cases better

in my head that sounds like:

Find all (resources) posts in (the subtree) organization:org1 that user john can (permission) read

benkroeger avatar May 21 '24 21:05 benkroeger

@benkroeger in your above example, the permission is read on the post, but you're walking through organization:org1. My question is: do you just want to walk through organization:org1 or a specific permission/relation on organization? Sounds like just the org itself

josephschorr avatar May 21 '24 22:05 josephschorr

Now I see what you mean. So it's resource (organization:org1) only

benkroeger avatar May 22 '24 06:05 benkroeger

FWIW, we have the same use case and only the resource should suffice as well.

In our case it's like the GCP IAM model, but imagine limiting the lookup to resources reachable within a certain folder or project.

alechenninger avatar May 22 '24 22:05 alechenninger

Okay; with the work we've been doing as part of LR2 (see: https://github.com/authzed/spicedb/pull/1905), this might be a fairly straightforward thing to do as a followup; I'll have to give some more thought to the exact approach when intersections/exclusions are involved, but LR2 does open up the possibility.

josephschorr avatar May 23 '24 01:05 josephschorr