Accessibility

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,%20where%20unauthorized%20parts%20of%20the%20schema%20are%20treated%20as%20non-existent.%20It’s%20also%20different%20from%20%5Bauthorization%5D(/authorization/authorization), which makes checks while running, instead of before running.

Opt-In

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
end

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)
  end

  # 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?
      false
    else
      super
    end
  end
end

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 = error.fields.map(&:permission_level).uniq
    # Return a custom error
    GraphQL::AnalysisError.new("You need certain permissions: #{required_permissions.join(", ")}")
  end
end

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