GraphQL Schemas – From Design-time Introspection to Runtime Content Validation

Schemas are unavoidable in GraphQL….in my experience, more so than for REST APIs. I appreciate this because it leads to more contract-first API development. When you combine strict schemas and introspection, you enhance the client-side developer experience (DX). A great visual manifestation of this happens when you use the GraphQL client, there is no better way to discover an API, especially for power users. Even in Postman, GraphQL schemas and introspection are leveraged to augment the DX. There is no turning back from this.

It has been argued that from an API security perspective, GraphQL introspection, should be turned off to limit exposure. Is this acceptable, given how critical schemas are to DX? At the end of the day, the GraphQL schema is a source of truth that should always be readily available to the target developer. Making this information available in documentation or in a repo is a great starting point but it is not sufficient. If your target developers already work with API instances separated from prod, then turning off introspection in prod is an applicable best-practice as long as you can maintain introspection in a non-prod environment that is maintained by the API provider to optimize the DX.

From a security perspective, the GraphQL API provider is also interested in the GraphQL schema as it pertains to ingress content sanitization. Providers want to pre-check incoming content prior to directing it to their endpoints and use a number of pattern validation strategies such as requiring payloads to comply with the specific schema for the API they target.  With a new experimental capability, Layer7 API Gateway policies can be configured to validate incoming GraphQL queries and mutations against a GraphQL schema specified at design time. GraphQL query and mutations use their own syntax, different from JSON. This requires a new capability to interpret and validate these structures. Using this newly available Layer7 API Gateway assertion, the GraphQL schema is provided at design time by either pasting it from the source or by simply providing a GraphQL endpoint address for introspection. You can use this capability to validate incoming GraphQL requests from external sources prior to directing them to GraphQL endpoints protected by the Layer7 API Gateway. Other GraphQL validations that can be done in policy includes limiting GraphQL query depth, hiding debug information from errors coming back from protected endpoints, etc.

Loading schemas via introspection is convenient, and since the production instance of a graphQL API may have introspection turned off, the introspection calls used at design time is done directly from Policy Manager and at design time only.

For advanced GraphQL-capable users, you can tailor the GraphQL schema and augment it with your own restrictions that may not be declared in the actual implementation you protect. Reversely, you can also use this to expose a GraphQL subset’ API where only parts of the implemented schema are allowed. You can hide a property of a type completely at the edge.

GraphQL schemas are a critical asset for modern API providers. They should be readily available to an API’s target developer and they can be used for security purposes, as part of an API’s content sanitization protection measures. Turning off GraphQL introspection in production enhances an APIs security posture only to the extent that it represents “security by obscurity”. It is still a wise and low-cost precaution, especially if target developers use a non-prod instance.