Secure your GraphQL API with Persisted Documents
Execute only the GraphQL operations your apps need and reject everything else. Learn how persisted documents shrink your API's attack surface.
What are persisted documents?
A GraphQL endpoint allows executing complex arbitary queries. That flexibility is useful for developers, but a risk for production GraphQL APIs. Unless you are running a public GraphQL API, there is no reason for an unknown client to invent an ad-hoc operation in production.
A persisted document (also referred to as trusted document or persisted query) is a query, mutation, or subscription that that has a stable ID assigned and is known by the GraphQL server or Gateway.
Clients send the document ID and variables instead of the document string. Your GraphQL server or gateway loads the corresponding document from a persisted document store. All arbitary GraphQL operations are rejected.
Executing arbitary queries belongs into the development process, not the production environment.
Your application
sha256:7c6f…a92e
variables:
{ … }
Your GraphQL endpoint
Clients send a document ID; unknown operations never reach execution.
Why Persisted Documents?
persisted documents turn your GraphQL endpoint from an open execution surface into an allowlist.
The benefits reach far beyond security.
Shrink the Attack Surface
Unknown operations never reach parsing, validation, planning, or execution. Attackers cannot craft malicious queries against your production API.
The allowlist is enforced before any GraphQL query validation or execution happens.
Send Smaller Requests
A short document ID replaces the complete GraphQL document string on every request.
Mobile and low-bandwidth clients pay a fraction of the payload cost they would otherwise send on each HTTP call.
Know What Can Break
Validate schema changes against every operation and every active application version.
Breaking-change checks become precise instead of speculative.
Adopting Persisted Documents
Build an allowlist from your client operations, publish them to a store, and enforce it on your GraphQL endpoint.
- Step 1
Generate your document manifest
Extract the reviewed GraphQL operations from your client code and assign each one a stable document ID (e.g. SHA-256 hash). Generate the manifest with GraphQL Code Generator or Relay.
- Step 2
Write manifest to store or registry
Write the manifest to a blob storage such as S3 or use a schema registry such as Hive, which futher validates the manifest against your schema, groups it by app and version, and distributes the approved documents through its CDN.
- Step 3
Enforce on your GraphQL endpoint
Clients send hashes instead of operation strings. Your server, router, or gateway resolves each document ID via your store or schema registry and rejects anything that was not reviewed and published before execution.
Persisted Documents on Hive
From development to publishing to distribution and GraphQL endpoint enforcement, see how each part of the workflow fits together with the Hive Platform.
Arbitary vs. Allowlist Execution
Without an allowlist, any valid operation can run. A curious visitor or malicious actor has full access to your GraphQL schema and can craft potential harmful queries.
Disabling Introspection and disabling suggestions might reduce risk, but tools exist for reverse engineering the full GraphQL schema via brute-force.
What changes with persisted documents
With persisted documents, the runtime resolves a documentId against a published allowlist. Operations that were never reviewed, published, or shipped are rejected before they are ever executed.
- Only operations that passed code review can run
- Unpublished or tampered IDs are rejected outright
- No introspection-based discovery of hidden fields
Do not confuse this with APQ
Automatic Persisted Queries are a bandwidth optimization. An unknown ID is retried with the full query and stored automatically. persisted documents are registered through an authenticated delivery pipeline; production clients cannot add new operations.
query GetAccount { account { id } }
query ExploreAdmin { admin { users } }
query ExpensiveSearch(first: 99999)…
Open execution: any valid operation runs, whoever sends it.
GetAccount · web 4.8.0
No trusted document ID
Document not published
Trusted execution: only the documents you shipped are allowed to run.
Hive Console and App Deployments
App Deployments group persisted documents by application and version. Hive validates them against your schema, distributes them through its CDN, tracks their usage, and includes active versions in breaking-change checks for proposed schema changes.
Check on pull requests, publish on deploy
Generate a manifest from your client operations, verify it in CI, and publish it from your CD pipeline before the application that depends on it goes live.
- Generate — build the manifest from your client operations
- Check — run
hive app:checkin pull-request CI - Publish — run
hive app:create --publishfrom CD - Deploy — release only after documents are available
Because Hive knows which app versions are still active, you can alter your GraphQL schema with confidence.
storefront
Active deployments
GetAccount
sha256:2e94…ac18web · 4.8.0
CompleteCheckout
sha256:7c6f…a92eweb · 4.8.0
UpdateProfile
sha256:913d…be03ios · 12.2.1
Hive Console groups persisted documents by application and version.
Enforce It in Any GraphQL Runtime
Enforcement happens on your GraphQL endpoint. You do not need a dedicated router or gateway. Add simple middleware to your existing GraphQL server, use GraphQL Yoga, or choose a runtime with persisted document support built in.
Hive provides two ready-made options: the Rust Hive Router for high performance, or the JavaScriptHive Gateway for flexible customization. Both resolve published documents from the Hive CDN and reject arbitrary GraphQL documents.
The request path
- The client sends a
documentIdand variables - Your GraphQL runtime resolves that ID from the document store
- Unknown IDs stop there
- Known documents execute
Migrating an existing API
For an existing API, first observe requests arriving without IDs, migrate those clients, and only then enable strict enforcement. Hive's usage reporting tells you when it is safe to flip the switch.
Request
documentId
sha256:7c6f…a92eGraphQL runtime
Resolve ID from Hive CDN
Unknown IDs stop here.
GraphQL API
Execute persisted document
Variables and identity still validated.
The runtime resolves the document ID before any execution happens.
Why Choose Hive for persisted documents?
End-to-End Pipeline
- CLI — generate and check manifests inside your existing CI.
- Registry — validate documents against the live schema before publishing.
- CDN — distribute published documents globally to your runtimes.
Enforcement You Own
- Your Runtime — use GraphQL Yoga, custom middleware, Hive Router, or Hive Gateway.
- MIT License — every component is open source and self-hostable.
- No Lock-in — works alongside other vendors and existing runtimes.
Safe Schema Evolution
- Version Awareness — know which app versions still use an operation.
- Breaking-Change Checks — validate changes against active deployments.
- Usage Insights — retire fields and operations with evidence, not guesswork.
Frequently Asked Questions About Persisted Documents
What is the difference between persisted documents and Automatic Persisted Queries?
Automatic Persisted Queries (APQ) are a bandwidth optimization. When the server does not recognize an ID, the client retries with the full query and the server stores it automatically.
Persisted Documents are registered ahead of time through an authenticated delivery pipeline. Production clients cannot add new operations, which is what makes the allowlist a security boundary.
Do Persisted Documents replace authentication and authorization?
No. persisted documents are a boundary, not a silver bullet. Keep authentication, authorization, input validation, pagination limits, rate limiting, and demand controls in place.
A trusted operation can still receive hostile variables or be called at an abusive rate.
Is disabling introspection enough to secure a GraphQL API?
No. Hiding introspection only makes discovery slower; schemas can still be inferred from client bundles and field-suggestion errors. The security boundary is the allowlist of operations your API is willing to execute.
How do I adopt persisted documents on an existing API?
Start in observation mode: report requests that arrive without a document ID, identify the clients behind them, and migrate those clients to use persisted documents.
Once traffic without IDs of known clients drops to zero, enable strict enforcement in your GraphQL server, middleware, router, or gateway.
Do persisted documents work with GraphQL Federation?
Yes. Enforcement happens at the gateway or router, in front of your supergraph, so subgraphs are unaffected. Documents are validated against the composed supergraph schema before they are published.
Get Started with Persisted Documents
Begin with our step-by-step App Deployments guide, which walks you through generating a manifest, checking it in CI, publishing it, and enforcing it at your GraphQL edge.
Start building now