Hasura is powerful — and dangerously open by default.

To run it safely in production, especially in regulated or hostile environments,

a Zero Trust Architecture is not optional — it’s essential.

This post presents a layered, hardened deployment model for Hasura under zero trust principles.


1. Design Philosophy

"Never trust the network. Never trust the client. Always verify, at every layer."

We enforce:

  • No public surface without authentication
  • Strict identity propagation via JWT
  • Micro-segmentation for roles and routes
  • Immutable permissions
  • Audit everything

2. High-Level Architecture

[Client] → [API Gateway] → [Auth Proxy] → [Hasura] → [PostgreSQL]
                          ↘︎ [OPA / Authz]  
                          ↘︎ [JWT Signer]
  • All traffic goes through gateway
  • Auth proxy (e.g. Firebase Auth / custom) issues JWTs
  • OPA or equivalent enforces external authorization
  • Hasura trusts only verified JWTs via x-hasura-* claims

3. JWT Configuration in Hasura

Set the following environment vars:

HASURA_GRAPHQL_JWT_SECRET='{
  "type": "HS256",
  "key": "",
  "claims_namespace_path": "$.hasura"
}'
HASURA_GRAPHQL_AUTH_HOOK=https://opa.example.com/authorize
HASURA_GRAPHQL_ADMIN_SECRET=disable_this_in_zero_trust

🔥 Best Practice:

  • DO NOT use admin secret in production
  • DO NOT expose /v1/graphql directly to the internet
  • DO NOT allow unauthenticated roles unless locked-down

4. Permissions via Roles

Define strict roles with field and row-level filters.

Example: user role for table invoices

select:
  filter:
    owner_id: { _eq: X-Hasura-User-Id }
  columns:
    - id
    - amount
    - status

Use Hasura Console or metadata YAML to version-control permission rules.


5. API Gateway Layer

Use Envoy / Traefik / Kong / AWS API Gateway to:

  • Enforce HTTPS only
  • Strip any client-supplied x-hasura-* headers
  • Inject clean, signed JWTs
  • Rate-limit per role/IP/token
  • Block unknown routes (/_console, /v2/query, /v1alpha1)

6. Open Policy Agent (OPA) Integration

Add a sidecar or external OPA for dynamic policy checks:

  • Time-based access control
  • IP allowlists per tenant
  • Data-driven deny rules

OPA can inject headers like x-hasura-allowed: true,

which Hasura can read via custom auth hook logic.


7. Monitoring and Auditing

Use:

  • Hasura Events / Webhooks to log high-value actions
  • PostgreSQL log_statement for backend visibility
  • GraphQL depth/complexity limits to avoid DoS

Example:

HASURA_GRAPHQL_ENABLE_TELEMETRY=false
HASURA_GRAPHQL_ENABLE_CONSOLE=false
HASURA_GRAPHQL_ENABLED_LOG_TYPES=startup,http-log,webhook-log

Push all logs to ELK / Loki / CloudWatch for long-term review.


Final Hardening Tips

  • 🛡 Remove public role entirely
  • 🔒 Disable console and metadata APIs
  • 🧠 Review permissions via CI on every schema change
  • 📶 Lock network ingress via security group / VPC firewall
  • 🎯 Adopt a deny-by-default policy — then allow per role

Final Thoughts

Hasura is GraphQL at hyperspeed — but that velocity cuts both ways.

If you're not running Zero Trust, you're trusting too much.

In upcoming articles:

  • Build a JWT issuing system for Hasura with short-lived tokens
  • Policy versioning for field-level access
  • Shadow mode attack detection via telemetry signals

Trust no one. Authorize everything. Harden by design.