Hi folks,
# spicedb
k
Hi folks, I'm exploring authorization patterns for GraphQL APIs with centralized authZ (OpenFGA, SpiceDB, Oso, etc.) and have some questions about real-world implementations: 1. Extracting authorization context from arbitrary nested queries For a query like:
Copy code
query {
    organizations {
      projects {
        documents {
          comments { ... }
        }
      }
    }
  }
How do you dynamically extract the (relation, object_type, object_id) tuple for each nested level? 2. Field-level authorization modeling For field-level permissions where read/write differ, how do you model this in a ReBAC model? 3. Mutations and write authorization For mutations that touch multiple objects: mutation { updateProject(id: "123", input: { name: "New Name", ownerId: "user_456" # requires special permission }) { ... } } - How do you check different permissions for different input fields? - Do you validate before execution, during resolver, or both? Would love to hear how others have approached this at scale?
y
1. you can't really know the resource IDs ahead of time. you're doing normal list logic, either prefiltering or postfiltering, depending on what makes sense for the particular resolver. 1. you have a definition corresponding to the resource and then a permission corresponding to each field 1. bulkcheck for each resource/permission. if any of them fail, fail the entire query. though i'd say a lot of this comes down to the business logic that you want in your application rather than any particular detail of SpiceDB or GraphQL.
we did find at my old company that one important part of the picture was that resolvers based on bulk methods worked a lot better than individual resolvers
b
We use dataloaders to batch bulk permission checks across resolvers, so for example if the Users service has separate resolvers/permissions for say, a user's name vs email, the following query would only hit SpiceDB once even though it's hitting 2 resolvers:
Copy code
query {
   user(id: ...) { firstName, email }
}
And if the
view_email
permission is denied we can still return the
firstName
, with a field-level authorization error for the
email
We use this pattern with a GraphQL Gateway in front, the gateway itself doesn't perform any authorization. Seems to work quite well even with fairly complicated queries distributed across various services.
18 Views