# Security showcase: GraphQL Armor vs Envelope vs authz ![](https://i.imgur.com/VHeeaSH.png) ## Security Let’s talk about security: a significant part of every stable application #### Authentication vs Authorization Authentication is determining whether a given user is logged in, and subsequently determining which user someone is. Authorization is then determining what a given user has permission to do or see. #### Other security problems Denial of Service DoS (Expensive queries) Insecure default configurations (e.g. excessive errors, introspection, etc.). Rate Limit bypass (Query complexity) Batching attacks (Several queries in one) ## How to GraphQL ![](https://i.imgur.com/XIOn0Mb.png) ## Authorization ### GraphQL Shield GraphQL Shield is an Authorization & Access Control middleware. We use it now, but it is currently **unmaintained**. - Based on GraphQL Middleware (wraps all resolvers - data-resolving phase). - Can fail the request during the execution phase which happens before the post-execution phase but later than the pre-execution phase - Built-in contextual caching mechanism for rules ### [GraphQL AuthZ](https://github.com/AstrumU/graphql-authz) <!-- https://the-guild.dev/blog/graphql-authz --> - Authorization layer - Wraps entire execution phase: runPreExecutionRules, runPostExecutionRules - For schema-first approach: Add rules and directive definition to the schema ```ts type Query { testQuery: TestType! @authz(rules: [IsAuthenticated]) } directive @authz( rules: [AuthZRules] compositeRules: [AuthZDirectiveCompositeRulesInput] deepCompositeRules: [AuthZDirectiveDeepCompositeRulesInput] ) on FIELD_DEFINITION | OBJECT | INTERFACE ``` Pros: - Failing early in the pre-execution phase (With GraphQL AuthZ it's possible to execute authorization logic before any of the resolvers have been executed. This empowers you to fail the request in the early stage, send back an error and reduce server workload.) - Post-execution rules have the benefit of accessing the resolved value of the field they are specified Cons: - Failing not early for post-execution rules - No built-in caching, but you can implement it yourself within the GraphQL AuthZ rules ### GraphQL Envelop (operation-field-permissions plugin) https://graphql.wtf/episodes/47-operation-field-permissions-with-envelop - allows to specify what plugins can be used based on the permissions of a user that requesting your api - `useOperationFieldPermissions` - `permissions` in database which specifies which fields the one can see Cons: - no difficult calculations: need to do in resolvers ### Which approach to choose for authorization? https://the-guild.dev/blog/graphql-authz#which-approach-to-choose Let's wrap up all the use-cases mentioned above and also give a library recommendation. - If you have very few places that should be covered by authorization, and you don't plan to increase such places, you can just add authorization logic right inside resolvers to not overcomplicate things. - If all of your authorization logic doesn't depend on the data and shouldn't perform complex calculations, you can use operation-field-permissions Envelop plugin. - If your authorization logic contains some calculations which are the same for many fields of your schema, you can use GraphQL Shield to leverage the built-in contextual caching mechanism. - If your authorization logic heavily depends on the data, or you want to use schema directives to attach auth rules, you can use GraphQL AuthZ to leverage the 'GraphQL schema as a data source' pattern and post-execution rules. ## GraphQL Armor > a middleware to make GraphQL more secure than REST in minutes ### What is it for? GraphQL's vulnerable nature mostly comes from the ability to create very large queries. In theory, you can fetch all the data from any GraphQL endpoint in just one very big API call. In practice what often happens instead when someone runs a very big query is: - Denial of Service - Leaking information from a badly coded resolver - Rate limiting bypass GraphQL Armor avoids all this by putting reasonable limits to what can be fetched from a single API call Complementory to Shield/AuthZ https://graphql.wtf/episodes/55-graphql-armor https://www.reddit.com/r/graphql/comments/wf5nl4/graphql_armor_a_middleware_to_make_graphql_more/ ### Functionality Disabling field suggestions Query depth limiting Query cost limits Alias limits Character limits Directive limits Batched and stacktraces Armor plans to support top features of Shield/AuthZ: ![](https://i.imgur.com/PTFsRPo.png)