Deployment
fold ships as two artifacts from one codebase. Pick per environment — the config format, auth model, and behavior are identical.
Node.js (self-hosted / VPC)
Section titled “Node.js (self-hosted / VPC)”pnpm install && pnpm buildnode apps/gateway-node/dist/index.mjs --config fold.config.json --port 8080Docker:
docker build -f apps/gateway-node/Dockerfile -t fold-gateway .docker run -p 8080:8080 -v $PWD/fold.config.json:/app/fold.config.json fold-gatewayMulti-instance: set REDIS_URL and every instance shares cache, rate-limit windows, circuit-breaker state, and legacy sessions — any request can land on any instance. Without Redis, stores are in-memory and correct for a single instance only.
Secrets: secretRef values resolve to environment variables (TEST_STATIC_SECRET, FOLD_EMA_KEY, …). Inject via your orchestrator’s secret mechanism.
Health: GET /healthz (liveness), GET /readyz (config loaded), GET /health/upstreams (per-upstream circuit state; Bearer-guarded when auth is required).
Cloudflare Workers (edge)
Section titled “Cloudflare Workers (edge)”cd apps/gateway-workersnpx wrangler deployFOLD_CONFIGvar carries the config JSON (use a secret for configs containing anything sensitive; prefersecretRef+ Workers secrets for credentials).FOLD_CACHEKV namespace backs the response/JWKS/token caches (optional — omitting it falls back to in-isolate memory).RATE_LIMITERandSESSIONSDurable Objects provide strongly consistent rate limiting and legacy-session storage; already declared inwrangler.jsoncwith SQLite-class migrations.- Local development:
npx wrangler devwith a.dev.varsfile containingFOLD_CONFIG=....
Observability
Section titled “Observability”fold instruments itself with OpenTelemetry (@opentelemetry/api): a server span per gateway hop (mcp.method.name, mcp.tool.name, fold.upstream.id, authz decision, status), request/duration metrics, and W3C trace context propagated from callers through to upstreams. Spans materialize when the host process registers a provider:
// Node: alongside the gateway entry, before servingimport { NodeSDK } from '@opentelemetry/sdk-node';new NodeSDK({ /* OTLP exporter config */ }).start();Without a registered provider the instrumentation is a no-op — zero configuration required to ignore it.
Production checklist
Section titled “Production checklist”-
auth.mode: "required"with your IdP as a trusted issuer (or EMA). -
server.allowedHostsset to your public hostname(s). -
policywithdefaultDecision: "deny"and explicit allow rules. -
audit.sinkspointed at your log pipeline / SIEM. - Upstream
authstrategies set (prefertoken-exchange); nopassthroughwithout understanding the audience caveat. - Node multi-instance:
REDIS_URLconfigured. - TLS terminated in front of fold (LB/ingress) — fold serves plain HTTP.