GraphQL Ruby and Authorization With Pundit

Recently I began exploring GraphQL for use with Ruby on Rails. There is an excellent gem graphql created by Robert Mosolgo , that provides all the workings of GraphQL https://github.com/rmosolgo/graphql-ruby. Notably is the excellent documentation accompanying this gem https://rmosolgo.github.io/graphql-ruby.

With all the documentation you should easily be able to get up and running with GraphQL in Ruby. However, authorizing user access to records via Pundit may require a bit of exploration, seeing as it’s original intended purpose is to authenticate by controller actions. I’m going to quickly outline how I achieved this with a few code snippets. First add Pundit to you gemfile: gem 'pundit.

Then in your Application Controller:

Now you’ll need a controller to serve the GraphQL queries. Let’s call it graphql_controller.rb. As you can see below, GraphqlController inherits from ApplicationController, thus giving us Pundit capabilities. To make things simple, we have passed in a context with the current_user and pundit -which will give us access to the Pundit authorize method in the GraphQL handlers. Also, by passing the instance of the controller into the context, we are able to add after_action :verify_authorized to ensure policies and scopes are used somewhere in the GraphQL handlers.

Next, if you’re using Relay you should put a Pundit authorize in your schema where you decode the object id. You can see that we have used the pundit instance passed into the context (ctx). Because we are simply looking up a record here, we have decided to use the :show policy action.

If you happen to come across this demo app , you’ll notice an abstraction for fetching records called FetchFeild. I’ll add an example below in case you also have chosen this route. In the resolve method below, we add in a Pundit authorize call to ensure the user has access to the record that is being fetched. Pundit will automatically lookup the policy by model name (class name) and authorize accordingly.

Lastly, when doing mutations (or even queries), you’ll need to add your authorization to create or update the record. Below we have a mutation to create a Post. We add the authorize call in the resolve proc. Note that we are using a headless policy for Pundit here: i.e. authorize :post.

Hopefully this will get you moving along with Pundit authorization a bit faster.