Skip to content

dotcomrow/cf-suncoast-graphql-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cf-suncoast-graphql-proxy

Cloudflare Worker that acts as a strict pull-through proxy to an upstream GraphQL endpoint in your k8s cluster.

Behavior

  • Accepts GraphQL requests on /graphql (GET and POST).
  • Accepts Directus asset passthrough requests on /directus/assets/* (GET and HEAD).
  • Proxies requests to UPSTREAM_GRAPHQL_URL without local schema composition/resolvers.
  • Supports GraphQL subscription upgrades over WebSocket by forwarding required upgrade and Sec-WebSocket-* headers to upstream.
  • Preserves upstream schema exposure (including introspection behavior) because the worker does not host schema locally.
  • Enforces CORS allow-list via CORS_DOMAINS (exact origins and wildcard subdomain patterns like https://*.suncoast.systems or *.suncoast.systems); additionally allows localhost loopback origins only when the request hostname has a dev subdomain label.
  • Uses bearer-token passthrough only:
    • HTTP GraphQL requests (GET/POST) require Authorization: Bearer ...; missing/invalid bearer headers return 401 Not authorized.
    • WebSocket upgrade handshakes are allowed without Authorization so browser clients can connect; upstream GraphQL must enforce token auth during connection_init.
    • Valid Authorization: Bearer ... headers are forwarded to upstream unchanged.
  • Forwards client IP metadata to upstream using Cloudflare-trusted source only:
    • Reads only CF-Connecting-IP from the Cloudflare edge request.
    • Ignores inbound X-Forwarded-For, Forwarded, X-Real-IP, and True-Client-IP values from clients.
    • Sends normalized IP via X-Client-IP, X-Real-IP, CF-Connecting-IP, True-Client-IP, X-Forwarded-For, and Forwarded.
  • Provides edge caching for unauthenticated query operations.

Cache Rules

  • Cache is enabled by default and controlled via env vars.
  • Only query operations are cache candidates.
  • Requests with Authorization or Cookie are never cached.
  • Mutations/subscriptions are never cached.
  • POST query responses are cached with a SHA-256 body-based key.
  • Responses with Set-Cookie, Cache-Control: private, or Cache-Control: no-store are not cached.
  • By default, GraphQL responses containing errors are not cached (CACHE_INCLUDE_GRAPHQL_ERRORS=false).
  • WebSocket upgrade requests are always bypassed from cache and returned as raw upgraded responses.

Worker Env Bindings

  • UPSTREAM_GRAPHQL_URL: optional full upstream GraphQL URL override.
    • By default this is generated by Terraform from UPSTREAM_DNS_NAME, domain, and UPSTREAM_GRAPHQL_PATH.
  • UPSTREAM_TIMEOUT_MS (optional, default 120000): timeout for upstream GraphQL request before returning 504 (also used for WebSocket handshake timeout).
  • UPSTREAM_DIRECTUS_ASSET_BASE_URL (optional): base URL used for /directus/assets/* passthrough. If omitted, defaults to https://<UPSTREAM_DNS_NAME>.<domain>.
  • UPSTREAM_DIRECTUS_ASSET_PATH (default /assets): upstream path prefix appended to UPSTREAM_DIRECTUS_ASSET_BASE_URL.
  • DIRECTUS_ASSET_PROXY_PREFIX (default /directus/assets): public path prefix exposed by this worker for asset passthrough.
  • CORS_DOMAINS (required): comma-separated allowed origins. Supports exact origins and wildcard subdomain entries like https://*.suncoast.systems or *.suncoast.systems.
    • Terraform sets this from ALLOWED_HOSTS and automatically appends *.${domain}.
  • CACHE_ENABLED (default true).
  • CACHE_TTL_SECONDS (default 60).
  • CACHE_STALE_WHILE_REVALIDATE_SECONDS (default 30).
  • CACHE_INCLUDE_GRAPHQL_ERRORS (default false).

Terraform Upstream Ownership

  • This workspace does not create or manage upstream Cloudflare Tunnel DNS records.
  • UPSTREAM_DNS_NAME (default graphql-origin): relative DNS label for the externally managed upstream GraphQL hostname.
  • UPSTREAM_GRAPHQL_PATH (default /v1/graphql): path appended to the upstream hostname.
  • global-terraform-workspace owns graphql-origin.suncoast.systems through module.cloudflare_tunnel["graphql"].cloudflare_record.this.
  • global-terraform-workspace also owns the matching tunnel ingress config through module.cloudflare_tunnel["graphql"].cloudflare_zero_trust_tunnel_cloudflared_config.this.
  • Deprecated compatibility variables such as MANAGE_UPSTREAM_DNS_RECORD, MANAGE_UPSTREAM_TUNNEL_CONFIG, UPSTREAM_TUNNEL_ID, UPSTREAM_TUNNEL_SERVICE, and UPSTREAM_ORIGIN_IP are accepted by this module but have no effect.

Health Check

  • GET /healthz returns proxy health and version.
  • GET /upstream-probe performs a direct probe to UPSTREAM_GRAPHQL_URL and returns reachability/latency/status diagnostics.

About

Suncoast systems Cloudflare GraphQL proxy

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors