Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LookupResources, through object(s) #1317

Open
jwineinger opened this issue May 12, 2023 · 5 comments
Open

LookupResources, through object(s) #1317

jwineinger opened this issue May 12, 2023 · 5 comments
Labels
area/api v1 Affects the v1 API state/needs discussion This can't be worked on yet

Comments

@jwineinger
Copy link

jwineinger commented May 12, 2023

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

@josephschorr
Copy link
Member

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

@jzelinskie jzelinskie added area/api v1 Affects the v1 API state/needs discussion This can't be worked on yet labels May 22, 2023
@jwineinger
Copy link
Author

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.

@josephschorr
Copy link
Member

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

@jwineinger
Copy link
Author

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.

@Twonky-Chris
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/api v1 Affects the v1 API state/needs discussion This can't be worked on yet
Projects
None yet
Development

No branches or pull requests

4 participants