I already have a great answer about how multiple auth rules are handled over on Order of @auth directive Processing - #2 by michaelcompton, but what I want to know specifically here is if a node/Type has to pass the same auth rule multiple times if it is contained at different levels in the graph.
With schema example:
type User @auth(query: { rule: "{$LOGGED_IN: { eq: \"true\"}}" }) {
username: String! @id
name: String
}
type Post {
comments: [Comment]
author: User
likedBy: [User]
}
type Comment {
replies: Comment
author: User!
}
When I run:
query {
queryPost {
author { name }
comments {
author { name }
replies {
author { name }
}
}
likedBy { name }
}
}
The type User with the auth rule is found on multiple levels:
getPost.author
getPost.comments.author
getPost.comments.replies.author
getPost.likedBy
Does the processing of this query get the data and combines the rules on each level? I will try to explain this in pseudo code:
get Post {
get author.filter(User auth rules)
get comments {
get author.filter(User auth rules)
get replies {
get author.filter(User auth rules)
}
}
get likedBy.filter(User auth rules)
}
Or is it processed in a flattened structure (again explaining with pseudo):
filteredUsers as get Users.filter(User auth rules)
get Post {
get author from filteredUsers
get comments {
get author from filteredUsers
get replies {
get author from filteredUsers
}
}
getLikeBy from filteredUsers
}
It sort of feels like it processes the former way which would be easier to program but less performant. In my use case I have a deep data query and a type with a lot of rules heavy on query rules is present MANY times through the structure. It feels like it is slow because every use of the type calls a requery of the rules. This may not be the case, just how it feels though.
Personal Context
When I first started learning about graphs, I started at the docs and presentations by neo4j. I don’t have the source at hand anywhere, but when asked if adding more layers of authorization made the database slower, the response was no, it actually made it faster because it then it actually working with a smaller graph instead of a big giant one. It seemed like the auth rules in place actually sort of did a namespacing type feat within the graph so that querying a User type was not applying a set of rules each time, but rather querying only the smaller set of Users that was accessible given the ACL.
I understand that @auth directive is the poor man auth and that the real ACL is an enterprise feature that I have not learned yet (just haven’t seen the need yet). Maybe this is how the ACL feature works in the enterprise version by limiting the size of the graph making it actually faster instead of slower.
Performance Review
I have a query (based on my actual schema not the example above) that returns 25 contacts with what I would consider some basic information to form a table in a UI that then gets paginated by the user. I just looked at an example one and the query took 10 seconds—Not acceptable IMO. A user will get tired of waiting 10 seconds between each paginated table load especially when they are scanning the table for a specific item. Here is an actual extensions
response:
extensions: {touched_uids: 3692204,…}
touched_uids: 3692204
tracing: {version: 1, startTime: "2020-10-19T03:58:09.492724379Z", endTime: "2020-10-19T03:58:19.57221792Z",…}
duration: 10079493595
endTime: "2020-10-19T03:58:19.57221792Z"
execution: {,…}
resolvers: [{path: ["queryContact"], parentType: "Query", fieldName: "queryContact", returnType: "[Contact]",…}]
0: {path: ["queryContact"], parentType: "Query", fieldName: "queryContact", returnType: "[Contact]",…}
dgraph: [{label: "query", startOffset: 2848749, duration: 10072729121}]
0: {label: "query", startOffset: 2848749, duration: 10072729121}
duration: 10072729121
label: "query"
startOffset: 2848749
duration: 10076098192
fieldName: "queryContact"
parentType: "Query"
path: ["queryContact"]
0: "queryContact"
returnType: "[Contact]"
startOffset: 426432
startTime: "2020-10-19T03:58:09.492724379Z"
version: 1
If anyone wants to take a closer look at this exact issue, I can work privately with a link and the actual query and schema used. It has sensitive data so I cannot post it publicly.