Turn off playground in production
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
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 thanks for responding, no immediate rush but will prevent us from deploying to prod so if the release is due soon then great.
Might be good to have the option to disable introspection too
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 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;
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;
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?
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.
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.
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.
Great, the option of boolean + function with request context seems appropriate 💪
Hey @schettn, was there any further movement on this? We are looking to go into production end of next week.