pylon icon indicating copy to clipboard operation
pylon copied to clipboard

Turn off playground in production

Open mikefrancis opened this issue 1 year ago • 3 comments

Hi,

Is there anyway to turn off the playground, especially for production? I know Apollo Server turns off the dev tools if NODE_ENV=production, have tried this with Pylon but still seeing the playground.

Thanks

mikefrancis avatar Feb 14 '25 16:02 mikefrancis

Hi, currently this is hardcoded in pylon but I will make it configurable via the PylonConfig.

export const config: PylonConfig = {
  graphiql: false // process.env.NODE_ENV !== "production"
}

Is this important for you right now? If not I would like to add this feature in the upcoming v3 release https://github.com/getcronit/pylon/pull/66

schettn avatar Feb 14 '25 17:02 schettn

@schettn thanks for responding, no immediate rush but will prevent us from deploying to prod so if the release is due soon then great.

mikefrancis avatar Feb 14 '25 19:02 mikefrancis

Might be good to have the option to disable introspection too

mikefrancis avatar Feb 14 '25 19:02 mikefrancis

What done the trick for us in staging|production env, replace the get on /graphql with an error according to env configuraiton ==>

import { app } from "@getcronit/pylon"
import config from "../config.js"

if (!config.GQL_ALLOW_DEVTOOLS) app.get("/graphql", (c) => c.json({ status: "ko" }, 401))

@mxkxf in order to disallow introspection queries, you can add the required envelop plugin to your graphql config

const plugins: PylonConfig["plugins"] = [
	...(config.GQL_ALLOW_INTROSPECTION ? [] : [useDisableIntrospection()]),
]

or while waiting for the PylonConfig TS update mentionned above, we defined this shape ==>

import type { YogaServerOptions } from "graphql-yoga"
import { type Context } from "@getcronit/pylon"

const plugins: PylonConfig["plugins"] = [
	...(envConfig.GQL_ALLOW_INTROSPECTION ? [] : [useDisableIntrospection()]),
]

export const config: PylonConfig & YogaServerOptions<Context, Context> = {
	...(envConfig.GQL_ALLOW_DEVTOOLS ? {} : { graphiql: false }),
	maskedErrors: true,
	plugins,
}

MarcDanjou avatar Jun 03 '25 14:06 MarcDanjou

@MarcDanjou I guess one can do this as well?

import { app, PylonConfig } from '@getcronit/pylon';

if (process.env.NODE_ENV === 'production') app.get("/graphql", (c) => c.json({ status: "ko" }, 401));

export const config: PylonConfig = {
  plugins: [
    process.env.NODE_ENV === 'production' ? useDisableIntrospection() : null
  ]
};

export default app;

Which is easier for me to read.

Or using your example:

import { app, PylonConfig } from '@getcronit/pylon';
import envConfig from "../config.js";

if (!envConfig.GQL_ALLOW_DEVTOOLS) app.get("/graphql", (c) => c.json({ status: "ko" }, 401));

export const config: PylonConfig = {
  plugins: [
    envConfig.GQL_ALLOW_INTROSPECTION ? null : useDisableIntrospection()
  ]
};

export default app;

ckhatton-pvfscaffolding avatar Jun 23 '25 09:06 ckhatton-pvfscaffolding

I see there is also a GraphQL Viewer that still loads in production mode. Probably good to turn that off for production too...

import { app } from '@getcronit/pylon';

if (process.env.NODE_ENV === 'production') app.get("/viewer", (c) => c.json({ status: "ko" }, 401));

export default app;

ckhatton-pvfscaffolding avatar Jun 23 '25 13:06 ckhatton-pvfscaffolding

The config option (graphiql: false) is now also added after merging #94.

Should disabling graphiql also automatically disable introspection, or do you want to add the plugin yourself?

schettn avatar Jul 01 '25 05:07 schettn

Thanks @schettn

Some of our clients are allowed to introspect, based on their credentials, so my guess would be to:

  • let developpers toggle the introspection manually
  • maybe add a { introspection: boolean } option in the grahql server ?

Could we also add a { viewer: boolean } to disable voyager the same way ? As the override of hono routing on /viewer mentionned above didn't work for us.

Alahel avatar Jul 01 '25 06:07 Alahel

Yeah I agree, some clients would like their API to be a public one in production (SaaS products) and thus introspection and the viewer would be useful in that scenario.

ckhatton-pvfscaffolding avatar Jul 01 '25 08:07 ckhatton-pvfscaffolding

Both /graphql (the GraphiQL UI) and /viewer rely on introspection to work properly. So if introspection is turned off, they won’t function correctly.

To make things simpler, I suggest adding a single graphiql flag that controls all three together: the GraphiQL UI at /graphql, the /viewer endpoint, and introspection itself. When this flag is on, all three are enabled to make development easier. When it’s off, they’re all disabled to tighten security in production.

For cases where introspection should only be available conditionally—like only for authorized users—graphiql could either be:

  • A simple on/off boolean that controls everything globally, or
  • A function that takes the request context (getContext()) and decides per request whether to enable these features, based on things like user credentials.

This way, configuration is straightforward, nothing breaks unexpectedly, and there’s flexible control over who can use the developer tools and access introspection.

Do you think there are scenarios where someone would want to disable just one of these but keep the others active? Since introspection is essential for both /graphql UI and /viewer, bundling them under a single flag seems like a cleaner and safer approach.

schettn avatar Jul 03 '25 15:07 schettn

Great, the option of boolean + function with request context seems appropriate 💪

MarcDanjou avatar Jul 03 '25 15:07 MarcDanjou

Hey @schettn, was there any further movement on this? We are looking to go into production end of next week.

ckhatton-pvfscaffolding avatar Sep 25 '25 07:09 ckhatton-pvfscaffolding