If someone is looking for a dynamic option, an approach might be to use a custom Analyzer.
- Pass a context variable such as authorize_introspection when calling your schema:
class GraphqlController < ApplicationController
def execute
context = context.merge(authorize_introspection: admin?)
result = MySchema.execute(query,
variables: variables,
context: context,
operation_name: operation_name,
root_value: root_value
)
render json: result.to_json
end
(...)
- Then use it here
class QueryAnalyzer < GraphQL::Analysis::AST::Analyzer
def on_leave_field(_node, _parent, visitor)
introspection_field_names = %w[__schema __type]
field_def = visitor.field_definition
if field_def.introspection? && introspection_field_names.include?(field_def.graphql_name)
@introspection_present = true
end
super
end
def result
return if introspection?
GraphQL::AnalysisError.new('Not authorized to query schema internals')
end
private
def introspection?
@introspection_present && introspection_authorized?
end
def introspection_authorized?
ENV['DISABLE_INTROSPECTION_ENTRY_POINTS'] != 'true' && query.context[:authorize_introspection]
end
end
- Make the declaration on the schema
class MySchema < GraphQL::Schema
use GraphQL::Analysis::AST
query_analyzer QueryAnalyzer
(...)
end
source: https://github.com/rmosolgo/graphql-ruby/issues/1240#issuecomment-393936456