> GraphQL Permissions Framework For Complex Authorisation Systems
> Implement your server permissions in a clear and deterministic way and let it guard access to your schema.
https://www.graphql-shield.com/
Define rule functions, each query/mutation can be authorized by one or multiple rules.
## Example
```js
import { shield, rule, and, or } from 'graphql-shield'
const isAdmin = rule()(async (parent, args, ctx, info) => {
return ctx.user.role === 'admin'
})
const isEditor = rule()(async (parent, args, ctx, info) => {
return ctx.user.role === 'editor'
})
const isOwner = rule()(async (parent, args, ctx, info) => {
return ctx.user.items.some((id) => id === parent.id)
})
const permissions = shield({
Query: {
users: or(isAdmin, isEditor),
},
Mutation: {
createBlogPost: or(isAdmin, and(isOwner, isEditor)),
},
User: {
secret: isOwner,
},
})
```
## Custom Errors
This is important and often an easy to ignore point.
When I throw errors (even if the mutation has nothing to do with shield), the server always return `INTERNAL_SERVER_ERROR`, no matter what type of error I throw. Everything back to normal if I stop using shield.
https://www.graphql-shield.com/docs/errors#custom-errors
> Shield, by default, catches all errors thrown during resolver execution. This way we can be 100% sure none of your internal logic can be exposed to the client if it was not meant to be.
> To return custom error messages to your client, you can **return error instead of throwing it**. This way, Shield knows it's not a bug but rather a design decision under control. Besides returning an error you can also return a string representing a custom error message.
> You can return custom error from resolver or from rule itself. Rules that return error are treated as failing, therefore not processing any further resolvers.