Statamic Graphql Protect Icon

Statamic Graphql Protect

Statamic Graphql Protect Main Screenshot

πŸ” Secure your Statamic GraphQL endpoint
A lightweight, production-ready addon that protects Statamic’s /graphql endpoint using a token-based middleware with optional IP allow-listing.

Perfect for headless setups (Next.js, Nuxt, mobile apps) where public GraphQL access must be locked down without changing existing queries.

πŸ‘‰ Statamic Marketplace:
https://statamic.com/addons/emran-alhaddad/statamic-graphql-protect


πŸ“¦ Package Information

Statamic Addon Latest Version Total Downloads License Maintenance PRs Welcome


πŸš€ Features

  • πŸ” Token-protected /graphql endpoint
  • πŸ›‘οΈ Optional IP allow-list
  • 🧩 Works with Statamic’s GraphQL layer (Rebing GraphQL under the hood)
  • βš™οΈ Fully configurable via .env
  • πŸ—‚οΈ Middleware-based (no route overrides)
  • 🧼 No Statamic core hacks or forks

πŸ“¦ Installation

Install via Composer:

composer require emran-alhaddad/statamic-graphql-protect

Publish the config file:

php artisan vendor:publish --tag=statamic-graphql-protect

βš™οΈ Configuration

Published config file:

config/statamic-graphql-protect.php

Example .env configuration:

STATAMIC_GRAPHQL_PROTECT_ENABLED=true
STATAMIC_GRAPHQL_TOKEN=long-secreat-token
STATAMIC_GRAPHQL_TOKEN_HEADER=X-Statamic-GraphQL-Token
STATAMIC_GRAPHQL_ALLOWED_IPS=127.0.0.1,1.2.3.4

Your frontend must send the header:

X-Statamic-GraphQL-Token: <your-token>

⚠️ REQUIRED: Register Middleware in Statamic GraphQL Config

This addon does not automatically inject itself into every Statamic install.

You must manually register the middleware.

Open:

config/statamic/graphql.php

Add the middleware to the middleware array:

return [
 
// ...
 
'middleware' => [
\Emran\StatamicGraphqlProtect\Http\Middleware\ProtectGraphql::class,
// other GraphQL middleware (if any)
],
 
// ...
];

❗ Without this step, /graphql will remain public.


πŸ§ͺ Example Usage

❌ Request without token (blocked)

curl https://your-domain.com/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{ ping }"}'

Response:

{ "message": "Invalid or missing GraphQL token." }

βœ… Request with token (allowed)

curl https://your-domain.com/graphql \
-H "Content-Type: application/json" \
-H "X-Statamic-GraphQL-Token: your-token" \
-d '{"query":"{ ping }"}'

Response:

{ "data": { "ping": "pong" } }

πŸ”§ Postman Setup

  1. Headers
Key Value
X-Statamic-GraphQL-Token your-token
Content-Type application/json
  1. Body β†’ Raw β†’ JSON
{ "query": "{ ping }" }
  1. Send βœ…

⚠️ IMPORTANT: Disable Statamic GraphQL Cache

Statamic’s GraphQL cache does NOT respect request headers.

If enabled:

  • First unauthenticated request β†’ 401 cached β†’ everyone gets 401
  • First authenticated request β†’ 200 cached β†’ endpoint effectively public

βœ… Disable it:

Edit:

config/statamic/graphql.php
'cache' => false,

or:

'cache' => [
'expiry' => 0,
],

Then clear caches:

php artisan config:clear
php artisan cache:clear
php artisan statamic:stache:clear

βœ… Recommended: cache at Next.js / CDN / Edge level, not inside Statamic.


πŸ”„ Compatibility

  • βœ… Statamic v4 / v5
  • βœ… PHP 8.1+
  • βœ… Headless & traditional installs
  • βœ… Next.js / Nuxt / Mobile apps

πŸ“ Directory Structure

statamic-graphql-protect/
β”œβ”€ src/
β”‚ β”œβ”€ Http/Middleware/ProtectGraphql.php
β”‚ └─ ServiceProvider.php
β”œβ”€ config/statamic-graphql-protect.php
β”œβ”€ composer.json
β”œβ”€ README.md
└─ LICENSE

🩺 Troubleshooting

β€œInvalid or missing GraphQL token”

  • Header name mismatch
  • Token contains whitespace
  • Middleware not registered in config/statamic/graphql.php

Works in cURL but not Postman

  • Use Body β†’ Raw β†’ JSON
  • Ensure headers are manually added

Random 200 / 401 responses

  • GraphQL cache still enabled
  • Disable it and clear caches

πŸ‘€ Author

Emran Alhaddad GitHub: https://github.com/emran-alhaddad Statamic Addons: https://statamic.com/addons/emran-alhaddad


πŸ“„ License

MIT License See the LICENSE file for full details.