GraphQL Shield 2.0
See original GitHub issueWhere is graphql-shield
headed
First, thanks for all the great feedback you’ve all given me so far. While listening to you and thinking about what I want and how I would like to use graphql-shield
in my projects, I came to some conclusions, which will lead the second version of this package.
Whitelisting
The most requested feature and I, in my opinion, the most important one is whitelisting
. Whitelisting, in comparison to blacklisting, requires all the exposed queries to be explicitly allowed in order to be used. Adoption of whitelisting also brings a lot easier stage separation as queries/mutations can be allowed in the development phase and restricted in production.
interface Options {
debug: true // -> makes all the queries "available"
cache: true
}
Nesting permissions
Currently, graphql-shield
only supports nesting permissions using type-specific permissions, which get evaluated during execution chain.
const permissions = {
Query: {
me: authenticated
},
Me: {
id: isMe,
name: isMe,
secret: isMe
}
}
I think that the best approach to tackle this problem is by making possible lists
of permissions.
const permissions = {
Query: {
me: [authenticated, isMe]
},
}
As things get more complicated you might as well want to make some permissions optional (OR
), which would require helper functions like oneOf
and all
to make it all possible.
const permissions = {
Query: {
posts: oneOf(isAdmin, isEditor, isOwner),
oneTimeLatter: all(isAuthenticated, latterNotRead)
}
}
This is also the solution I am aiming for.
Allow entire type permissions
Right now, you can only restrict certain fields and the entire types
altogether. By introducing whitelisting
instead of blacklisting
this feature becomes essential as having to explicitly allow each field for each type is all too much work. In my opinion, making Type
general permissions available would perfectly solve this problem.
const permissions = {
Query: {
me: auth
},
Me: allowAllFields
}
Debugging
I think that most of the functionality should be directed to developers during the development stage. By introducing the right tools to make permission handling as easy as possible, we can make an actual difference with graphql-shield
.
Few ideas:
- Summary of all permissions in debug mode.
- Stage separation (as mentioned above) which would allow access to non-whitelisted queries to test and develop new permissions.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:17
- Comments:9
Top GitHub Comments
Looks like a good roadmap to me.
For what it’s worth, it’s not very hard to build your own permission composition on top of what you already have. I don’t think it’s really necessary to include a new resolver format like an array. Here’s what I’m working with so far (very WIP, just whipped this up in the last couple hours as I adopt this library):
Usage has been a breeze:
all
andany
are powerful enough for my needs. If I wanted to create a new Admin role with aupdateAnyTimeline
scope, for instance, I could just nest the existing scopes in anany
and write in the logic for that scope as anotherall
block.When my user authenticates, I load their scopes into the JWT token. That makes things super simple so far.
Being able to provide more detail would be great for testing and debugging. I think
setError
as described, though, represents a side-effect in an otherwise functional pattern.Another suggestion: allow users to return an Error instance instead of
false
, or allow them to return a more detailed object with a field to indicate permission status, and a description of the problem to pass to the user ({ failed: true, message: 'Please contact your account administrator to change your payment details', data: { /* etc */ } }
)