Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to enable GraphQL introspection in production #8014

Merged
merged 9 commits into from
Apr 25, 2023
27 changes: 26 additions & 1 deletion docs/docs/graphql.md
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,32 @@ Because it is often useful to ask a GraphQL schema for information about what qu

The [GraphQL Playground](https://www.graphql-yoga.com/docs/features/graphiql) is a way for you to interact with your schema and try out queries and mutations. It can show you the schema by inspecting it. You can find the GraphQL Playground at http://localhost:8911/graphql when your dev server is running.

> Because both introspection and the playground share possibly sensitive information about your data model, your data, your queries and mutations, best practices for deploying a GraphQL Server call to disable these in production, RedwoodJS **only enables introspection and the playground when running in development**. That is when `process.env.NODE_ENV === 'development'`.
> Because both introspection and the playground share possibly sensitive information about your data model, your data, your queries and mutations, best practices for deploying a GraphQL Server call to disable these in production, RedwoodJS **, by default, only enables introspection and the playground when running in development**. That is when `process.env.NODE_ENV === 'development'`.

However, there may be cases where you want to enable introspection. You can enable introspection by setting the `allowIntrospection` option to `true`.

Here is an example of `createGraphQLHandler` function with the `allowIntrospection` option set to `true`:
```ts {8}
export const handler = createGraphQLHandler({
authDecoder,
getCurrentUser,
loggerConfig: { logger, options: {} },
directives,
sdls,
services,
allowIntrospection: true, // 👈 enable introspection in all environments
onException: () => {
// Disconnect from your database with an unhandled exception.
db.$disconnect()
},
})
```

:::caution

Enabling introspection in production may pose a security risk, as it allows users to access information about your schema, queries, and mutations. Use this option with caution and make sure to secure your GraphQL API properly.

:::

### GraphQL Armor Configuration

Expand Down
8 changes: 7 additions & 1 deletion docs/docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ GraphQL is a fundamental part of Redwood. For details on how Redwood uses GraphQ
The RedwoodJS GraphQL handler sets [reasonable defaults](graphql.md#security) to prevent abusive queries that attackers often use to exploit systems.
### Disable Introspection and Playground

Because both introspection and the playground share possibly sensitive information about your data model, your data, your queries and mutations, best practices for deploying a GraphQL Server call to [disable these in production](graphql.md#introspection-and-playground-disabled-in-production), RedwoodJS **only enables introspection and the playground when running in development**.
Because both introspection and the playground share possibly sensitive information about your data model, your data, your queries and mutations, best practices for deploying a GraphQL Server call to [disable these in production](graphql.md#introspection-and-playground-disabled-in-production), By default RedwoodJS **only enables introspection and the playground when running in development**.
callingmedic911 marked this conversation as resolved.
Show resolved Hide resolved

:::note
<!-- Link to graphql.md docs -->
For more information on how to enable introspection in production, please see the [GraphQL Docs](graphql.md#introspection-and-playground-disabled-in-production).
:::

## Functions

When deployed, a [serverless function](serverless-functions.md) is an open API endpoint. That means anyone can access it and perform any tasks it's asked to do. In many cases, this is completely appropriate and desired behavior. But there are often times you need to restrict access to a function, and Redwood can help you do that using a [variety of methods and approaches](serverless-functions.md#security-considerations).
Expand Down
6 changes: 5 additions & 1 deletion packages/graphql-server/src/functions/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const createGraphQLHandler = ({
directives = [],
armorConfig,
allowedOperations,
allowIntrospection,
defaultError = 'Something went wrong.',
graphiQLEndpoint = '/graphql',
schemaOptions,
Expand Down Expand Up @@ -93,7 +94,10 @@ export const createGraphQLHandler = ({

const plugins: Array<Plugin<any>> = []

if (!isDevEnv) {
if (
(allowIntrospection == null && !isDevEnv) ||
allowIntrospection === false
) {
plugins.push(useDisableIntrospection())
}

Expand Down
7 changes: 7 additions & 0 deletions packages/graphql-server/src/functions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ export interface GraphQLHandlerOptions {
* Defaults to '/graphql' as this value must match the name of the `graphql` function on the api-side.
*/
graphiQLEndpoint?: string

/**
* @description Allow schema introspection.
* By default, schema introspection is disabled in production. Explicitly set this to true or false to override in all environments.
*/
allowIntrospection?: boolean

/**
* @description Function that returns custom headers (as string) for GraphiQL.
*
Expand Down