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.