NOTE: This kind of authorization is deprecated and isn’t supported by the forthcoming GraphQL runtime because it’s too slow.

With GraphQL-Ruby, you can inspect an incoming query, and return a custom error if that query accesses some unauthorized parts of the schema.

This is different from visibility, where unauthorized parts of the schema are treated as non-existent. It’s also different from authorization, which makes checks while running, instead of before running.


To use this kind of authorization, you must add a query analyzer:

class MySchema < GraphQL::Schema
  # Set up ahead-of-time `accessible?` authorization
  query_analyzer GraphQL::Authorization::Analyzer

Preventing Access

You can override some .accessible?(context) methods to prevent access to certain members of the schema:

These methods are called with the query context, based on the hash you pass as context:.

Whenever that method is implemented to return false, the currently-checked field will be collected as inaccessible. For example:

class BaseField < GraphQL::Schema::Field
  def initialize(preview:, **kwargs, &block)
    @preview = preview
    super(**kwargs, &block)

  # If this field was marked as preview, hide it unless the current viewer can see previews.
  def accessible?(context)
    if @preview && !context[:viewer].can_preview?

Now, any fields created with field(..., preview: true) will be visible to everyone, but only accessible to users where .can_preview? is true.

Adding an Error

By default, GraphQL-Ruby will return a simple error to the client if any .accessible? checks return false.

You can customize this behavior by overriding Schema.inaccessible_fields, for example:

class MySchema < GraphQL::Schema
  # If you have a custom `permission_level` setting on your `GraphQL::Field` class,
  # you can access it here:
  def self.inaccessible_fields(error)
    required_permissions =
    # Return a custom error"You need certain permissions: #{required_permissions.join(", ")}")

Then, your custom error will be added to the response instead of the default one.