@burdenoff/be-sdk 2026.825.1 → 2026.825.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cache/index.d.ts +1 -1
- package/dist/cache/index.js +2 -1
- package/dist/{chunk-WMICUFAN.js → chunk-4X5WL6I3.js} +32 -7
- package/dist/chunk-4X5WL6I3.js.map +1 -0
- package/dist/chunk-A5F6Z5UE.js +21 -0
- package/dist/chunk-A5F6Z5UE.js.map +1 -0
- package/dist/{chunk-NSGICODT.js → chunk-AW6JUXCU.js} +66 -4
- package/dist/chunk-AW6JUXCU.js.map +1 -0
- package/dist/{chunk-BH5T72N3.js → chunk-L3QCRJOA.js} +3 -3
- package/dist/{chunk-BH5T72N3.js.map → chunk-L3QCRJOA.js.map} +1 -1
- package/dist/{chunk-SDSA6HAY.js → chunk-LGTQ26Z2.js} +3 -3
- package/dist/{chunk-SDSA6HAY.js.map → chunk-LGTQ26Z2.js.map} +1 -1
- package/dist/{chunk-MJDXQJJZ.js → chunk-NVVWSOY7.js} +2 -2
- package/dist/{chunk-MJDXQJJZ.js.map → chunk-NVVWSOY7.js.map} +1 -1
- package/dist/export/index.js +4 -3
- package/dist/gateway/index.js +3 -2
- package/dist/gateway/security/index.js +1 -1
- package/dist/{index-N8DMWKzw.d.ts → index-BCelo6F3.d.ts} +16 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/init/index.js +4 -3
- package/package.json +1 -1
- package/dist/chunk-NSGICODT.js.map +0 -1
- package/dist/chunk-WMICUFAN.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gateway/security/index.ts","../src/gateway/security/actor.ts","../src/gateway/security/cost-map.ts","../src/gateway/security/tiers.ts","../src/gateway/security/defaults.ts","../src/gateway/security/valkey.ts","../src/gateway/security/metrics.ts","../src/gateway/security/plugins/armor.ts","../src/gateway/security/plugins/operation-timeout.ts","../src/gateway/security/plugins/otel.ts","../src/gateway/security/plugins/query-complexity.ts","../src/gateway/security/plugins/rate-limit.ts","../src/gateway/security/plugins/index.ts"],"names":["firstIp","header","undefined","split","trim","classify","actorType","actorRole","resolveActor","getHeader","actorId","workspaceId","tenantId","orgId","appId","ip","tier","identity","headers","DEFAULT_COST_MAP","mergeCostMap","base","override","DEFAULT_TIERS","public","points","duration","burst","user","app","service","super_admin","Number","MAX_SAFE_INTEGER","positiveInt","value","fallback","parsed","parseInt","isFinite","resolveTiersFromEnv","out","Object","keys","forEach","upper","toUpperCase","process","env","boolEnv","key","v","intEnv","strEnv","DEFAULT_ARMOR_CONFIG","maxAliases","maxTokens","maxDirectives","characterLimit","costLimit","observe","resolveSecurityOptionsFromEnv","gatewayName","costMapOverride","enabled","armor","queryComplexity","maxCost","costMap","rateLimit","tiers","keyPrefix","observeOnly","failClosed","perWorkspace","operationTimeout","timeoutMs","otel","serviceName","endpoint","defaultCollectorTracesEndpoint","environment","version","IoRedisAdapter","client","get","set","options","EX","incrBy","amount","incrby","expire","seconds","result","ttl","ping","buildIoRedisClient","url","spec","mod","Ctor","default","Redis","Error","on","err","e","String","logger","warn","error","message","MemoryValkey","store","Map","prune","expiresAt","Date","now","delete","Promise","resolve","next","Math","max","ceil","singleton","bootPromise","initializeSecurityValkey","required","clientKind","msg","attempts","push","kind","factory","getValkeyClient","lastError","attempt","pong","info","getSecurityValkey","__setSecurityValkeyForTest","metrics","initializing","promMod","noopCounter","inc","noopMetrics","complexityRejected","armorRejected","valkeyFailover","initializeMetrics","imported","Counter","name","help","labelNames","getMetrics","scrapeMetrics","register","body","contentType","__resetMetricsForTest","tryImport","specifier","pickFactory","candidates","fn","createMaxAliasesRule","context","aliases","Field","node","alias","reportError","GraphQLError","nodes","extensions","code","createMaxDirectivesRule","directives","Directive","isLean","loadRules","cfg","lean","aliasesMod","directivesMod","costMod","blockSuggestionsMod","all","loaded","maxAliasesFactory","maxAliasesRule","n","exposeLimits","maxDirectivesFactory","maxDirectivesRule","costLimitFactory","costLimitRule","objectCost","scalarCost","depthCostFactor","ignoreIntrospection","blockSuggestionsFactory","blockSuggestionsPlugin","createArmorPlugins","rules","enabledRules","rule","armorValidationPlugin","onParse","params","source","length","limit","mode","http","status","onValidate","setResult","armorErrors","errs","graphqlValidate","schema","documentAST","wrapped","originalError","plugins","createTimeoutHandle","timerRef","promise","_","reject","setTimeout","timer","createOperationTimeoutPlugin","deps","timeoutError","config","onExecute","executeFn","setExecuteFn","args","handle","race","clearTimeout","shutdownHook","buildResource","resMod","attrs","resourceFromAttributes","Resource","resolveSemanticKeys","semcon","SemanticResourceAttributes","SERVICE_NAME","deploymentEnv","DEPLOYMENT_ENVIRONMENT","serviceVersion","SERVICE_VERSION","ATTR_SERVICE_NAME","ATTR_DEPLOYMENT_ENVIRONMENT_NAME","ATTR_DEPLOYMENT_ENVIRONMENT","ATTR_SERVICE_VERSION","loadOtelPeerDeps","sdkSpec","otlpSpec","resSpec","semSpec","modules","sdkMod","otlpMod","NodeSDK","OTLPTraceExporter","initializeOtel","resourceAttributes","sdk","resource","traceExporter","start","shutdown","shutdownOtel","createOtelPlugin","useOpenTelemetry","spans","execute","parse","validate","subscribe","resolvers","PAGINATION_ARGUMENTS","Set","MAX_LIST_MULTIPLIER","MAX_FAILURE_LOG_VARIANTS","complexityFailureMessages","isRecord","unwrapNamedType","type","current","getSchemaLike","getOperationRootType","operation","schemaLike","getMutationType","getSubscriptionType","getQueryType","getTypeByName","getType","getField","parentType","fieldName","getFields","getCostMapValue","numericValueFromAst","Kind","INT","FLOAT","STRING","listMultiplierFromArgs","arg","has","raw","min","trunc","calculateFieldComplexity","fieldNode","fragments","activeFragments","field","baseCost","namedFieldType","childCost","selectionSet","calculateSelectionSetComplexity","arguments","total","selection","selections","calculateSelectionComplexity","FIELD","INLINE_FRAGMENT","fragmentParent","typeCondition","fragmentName","fragment","add","complexity","calculateDocumentComplexity","operations","definition","definitions","FRAGMENT_DEFINITION","OPERATION_DEFINITION","maxComplexity","rootType","logComplexityFailure","seen","size","suppressedRepeats","debug","createQueryComplexityPlugin","gateway","cost","keyFor","prefix","wsKeyFor","stamp","checkRateLimit","actor","decision","allowed","remaining","resetAtMs","count","valkey","checkWorkspaceRateLimit","createRateLimitPlugin","onRequest","request","fetchAPI","endResponse","__rateLimitResult","__rateLimitActor","wsResult","retryAfterS","JSON","stringify","errors","scope","resetAt","toISOString","Response","floor","response","onResponse","stash","buildSecurityPlugins","otelPlugin","armorPlugins"],"mappings":"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","file":"chunk-MJDXQJJZ.js","sourcesContent":["/**\n * Gateway Security Module — public API\n *\n * Plug-in stack for public GraphQL federation gateways:\n * graphql-armor, per-field query complexity, per-actor rate limiting,\n * operation-level AbortController, OpenTelemetry spans.\n *\n * Consumed by each public gateway via:\n * ```ts\n * import { buildSecurityPlugins, resolveSecurityOptionsFromEnv } from '@burdenoff/be-sdk/gateway/security';\n *\n * const plugins = await buildSecurityPlugins(\n * resolveSecurityOptionsFromEnv('wspace-public-gateway', { 'Query.customField': 100 })\n * );\n * // pass plugins into createGatewayRuntime({ plugins })\n * ```\n *\n * @module gateway/security\n * @category Gateway\n */\n\nexport { resolveActor } from './actor.js';\nexport { DEFAULT_COST_MAP, mergeCostMap } from './cost-map.js';\nexport { DEFAULT_ARMOR_CONFIG, resolveSecurityOptionsFromEnv } from './defaults.js';\nexport { DEFAULT_TIERS, resolveTiersFromEnv } from './tiers.js';\nexport type {\n ActorContext,\n ArmorConfig,\n CostMap,\n GatewaySecurityOptions,\n OperationTimeoutConfig,\n OtelConfig,\n QueryComplexityConfig,\n RateLimitConfig,\n RateLimitResult,\n SecurityValkeyClient,\n Tier,\n TierLimits,\n} from './types.js';\nexport { __setSecurityValkeyForTest, getSecurityValkey, initializeSecurityValkey, MemoryValkey } from './valkey.js';\nexport { __resetMetricsForTest, getMetrics, initializeMetrics, scrapeMetrics } from './metrics.js';\n\nexport {\n buildSecurityPlugins,\n createArmorPlugins,\n createOperationTimeoutPlugin,\n createOtelPlugin,\n createQueryComplexityPlugin,\n createRateLimitPlugin,\n checkRateLimit,\n initializeOtel,\n shutdownOtel,\n} from './plugins/index.js';\n","/**\n * Actor Resolver\n *\n * Derives an ActorContext from the headers that the gateway's auth middleware\n * already injects (`x-actor-*`, `x-workspace-id`, `x-tenant-id`, `x-org-id`,\n * `x-forwarded-for`). This is the identity used for rate-limit buckets and\n * OTel span enrichment.\n *\n * @module gateway/security/actor\n * @category Gateway\n */\n\nimport type { ActorContext, Tier } from './types.js';\n\ntype HeaderGetter = (name: string) => string | null | undefined;\n\nconst firstIp = (header: string | null | undefined): string | undefined => {\n if (!header) return undefined;\n // x-forwarded-for is a comma-separated list; take the left-most (client).\n return header.split(',')[0]?.trim() || undefined;\n};\n\nconst classify = (actorType: string | undefined, actorRole: string | undefined): Tier => {\n if (actorRole === 'super_admin') return 'super_admin';\n switch (actorType) {\n case 'user':\n return 'user';\n case 'app':\n return 'app';\n case 'service':\n case 'service_account':\n return 'service';\n case 'super_admin':\n return 'super_admin';\n default:\n return 'public';\n }\n};\n\n/**\n * Resolve the canonical ActorContext for a request.\n * Accepts a `HeaderGetter` so it is trivially testable with a plain function.\n */\nexport const resolveActor = (getHeader: HeaderGetter): ActorContext => {\n const actorId = getHeader('x-actor-id') ?? undefined;\n const actorType = getHeader('x-actor-type') ?? undefined;\n const actorRole = getHeader('x-actor-role') ?? undefined;\n const workspaceId = getHeader('x-workspace-id') ?? undefined;\n const tenantId = getHeader('x-tenant-id') ?? undefined;\n const orgId = getHeader('x-org-id') ?? undefined;\n const appId = getHeader('x-app-id') ?? undefined;\n const ip =\n firstIp(getHeader('x-forwarded-for')) || getHeader('x-real-ip') || getHeader('cf-connecting-ip') || undefined;\n\n const tier = classify(actorType, actorRole);\n\n let identity: string;\n switch (tier) {\n case 'super_admin':\n identity = 'bypass';\n break;\n case 'service':\n identity = `svc:${actorId ?? 'unknown'}`;\n break;\n case 'app':\n identity = `${tenantId ?? 'notenant'}:${appId ?? actorId ?? 'unknown'}`;\n break;\n case 'user':\n identity = `${workspaceId ?? 'nows'}:${actorId ?? 'unknown'}`;\n break;\n case 'public':\n default:\n identity = `ip:${ip ?? 'unknown'}`;\n }\n\n return {\n tier,\n identity,\n headers: {\n actorId,\n actorType,\n actorRole,\n workspaceId,\n tenantId,\n orgId,\n appId,\n ip,\n },\n };\n};\n","/**\n * Default query complexity cost map.\n *\n * Key format: \"TypeName.fieldName\". Values are base costs. List fields multiply\n * by the requested page size (up to 100) via the plugin's list-multiplier.\n *\n * Seeded from known high-cost queries across the Burdenoff federation:\n * search, analytics, reports, enumerations, introspection.\n *\n * Extend via `mergeCostMap(DEFAULT_COST_MAP, override)` in each gateway.\n *\n * @module gateway/security/cost-map\n * @category Gateway\n */\n\nimport type { CostMap } from './types.js';\n\nexport const DEFAULT_COST_MAP: CostMap = {\n // Cross-subgraph search — fanout\n 'Query.searchBigConsole': 200,\n 'Query.searchWorkspaces': 100,\n 'Query.searchTags': 80,\n\n // Aggregations\n 'Query.analyticsReport': 300,\n 'Query.usageReport': 250,\n 'Query.billingReport': 250,\n 'Query.auditLog': 150,\n\n // Enumeration risk (paginated lists)\n 'Query.listUsers': 50,\n 'Query.listWorkspaces': 50,\n 'Query.listFiles': 40,\n 'Query.listTags': 20,\n 'Query.listApps': 40,\n\n // Nested lists\n 'Workspace.members': 5,\n 'User.workspaces': 10,\n 'User.apps': 5,\n 'Tag.appliedTo': 5,\n\n // Introspection — expensive and abuse-prone in prod\n 'Query.__schema': 1000,\n 'Query.__type': 500,\n\n // Heavy writers\n 'Mutation.bulkImport': 500,\n 'Mutation.webhookTrigger': 100,\n};\n\nexport const mergeCostMap = (base: CostMap, override: CostMap): CostMap => ({\n ...base,\n ...override,\n});\n","/**\n * Default rate-limit tiers for public gateways.\n *\n * These defaults target a single pod; cross-pod fairness is provided by the\n * Valkey-backed counter. Tune via `GATEWAY_RATE_LIMIT_*` env vars.\n *\n * @module gateway/security/tiers\n * @category Gateway\n */\n\nimport type { Tier, TierLimits } from './types.js';\n\nexport const DEFAULT_TIERS: Record<Tier, TierLimits> = {\n // Public (anonymous) traffic is keyed per-IP. The previous 60+20=80/60s\n // ceiling (1.33 req/s sustained) was tight enough that a single heavy\n // frontend page load (≈15–30 GraphQL queries) plus a NAT-shared second\n // user could blow the bucket on benign traffic. Bumping to 120+60=180/60s\n // (3 req/s sustained) gives 2× headroom while staying ~40× below the\n // ~130 req/s single-pod compute floor measured under realistic load.\n public: {\n points: 120,\n duration: 60,\n burst: 60,\n },\n user: {\n points: 600,\n duration: 60,\n burst: 120,\n },\n app: {\n points: 3000,\n duration: 60,\n burst: 500,\n },\n service: {\n points: 6000,\n duration: 60,\n burst: 1000,\n },\n super_admin: {\n points: Number.MAX_SAFE_INTEGER,\n duration: 60,\n burst: Number.MAX_SAFE_INTEGER,\n },\n};\n\nconst positiveInt = (value: string | undefined, fallback: number): number => {\n if (!value) return fallback;\n const parsed = parseInt(value, 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n};\n\n/**\n * Read tier overrides from env.\n *\n * Env var pattern: `GATEWAY_RL_{TIER}_{POINTS|DURATION|BURST}`\n * Example: `GATEWAY_RL_USER_POINTS=1200`\n */\nexport const resolveTiersFromEnv = (base: Record<Tier, TierLimits> = DEFAULT_TIERS): Record<Tier, TierLimits> => {\n const out: Record<Tier, TierLimits> = { ...base };\n (Object.keys(base) as Tier[]).forEach((tier) => {\n const upper = tier.toUpperCase();\n out[tier] = {\n points: positiveInt(process.env[`GATEWAY_RL_${upper}_POINTS`], base[tier].points),\n duration: positiveInt(process.env[`GATEWAY_RL_${upper}_DURATION`], base[tier].duration),\n burst: positiveInt(process.env[`GATEWAY_RL_${upper}_BURST`], base[tier].burst),\n };\n });\n return out;\n};\n","/**\n * Gateway Security Defaults\n *\n * Production-safe defaults for the security plugin stack, and helpers to\n * assemble `GatewaySecurityOptions` from environment variables. Each field\n * honors an `*_OBSERVE*` flag so the hardening pass can soft-launch\n * observe-only before flipping to enforce.\n *\n * @module gateway/security/defaults\n * @category Gateway\n */\n\nimport { defaultCollectorTracesEndpoint } from '../../telemetry/collector-endpoint.js';\nimport { DEFAULT_COST_MAP, mergeCostMap } from './cost-map.js';\nimport { resolveTiersFromEnv } from './tiers.js';\nimport type { ArmorConfig, CostMap, GatewaySecurityOptions } from './types.js';\n\nconst boolEnv = (key: string, fallback: boolean): boolean => {\n const v = process.env[key];\n if (v === undefined) return fallback;\n return v === 'true' || v === '1';\n};\n\nconst intEnv = (key: string, fallback: number): number => {\n const v = process.env[key];\n if (!v) return fallback;\n const parsed = parseInt(v, 10);\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst strEnv = (key: string, fallback: string): string => process.env[key] ?? fallback;\n\n/**\n * Default armor thresholds for public gateways.\n */\nexport const DEFAULT_ARMOR_CONFIG: ArmorConfig = {\n maxAliases: 15,\n maxTokens: 1000,\n maxDirectives: 50,\n characterLimit: 15000,\n costLimit: 5000,\n observe: true,\n};\n\n/**\n * Build `GatewaySecurityOptions` by reading env vars.\n *\n * All defaults are production-safe but begin in observe-only mode so the\n * first deploy does not reject any traffic. Flip observe flags to `false`\n * after the 48h bake.\n */\nexport const resolveSecurityOptionsFromEnv = (\n gatewayName: string,\n costMapOverride?: CostMap\n): GatewaySecurityOptions => {\n return {\n gatewayName,\n enabled: boolEnv('SECURITY_PLUGINS_ENABLED', true),\n armor: {\n maxAliases: intEnv('ARMOR_MAX_ALIASES', DEFAULT_ARMOR_CONFIG.maxAliases),\n maxTokens: intEnv('ARMOR_MAX_TOKENS', DEFAULT_ARMOR_CONFIG.maxTokens),\n maxDirectives: intEnv('ARMOR_MAX_DIRECTIVES', DEFAULT_ARMOR_CONFIG.maxDirectives),\n characterLimit: intEnv('ARMOR_CHARACTER_LIMIT', DEFAULT_ARMOR_CONFIG.characterLimit),\n costLimit: intEnv('ARMOR_COST_LIMIT', DEFAULT_ARMOR_CONFIG.costLimit),\n observe: boolEnv('ARMOR_OBSERVE', true),\n },\n queryComplexity: {\n enabled: boolEnv('QUERY_COMPLEXITY_ENABLED', true),\n maxCost: intEnv('QUERY_COMPLEXITY_MAX', 2000),\n costMap: costMapOverride ? mergeCostMap(DEFAULT_COST_MAP, costMapOverride) : DEFAULT_COST_MAP,\n observe: boolEnv('QUERY_COMPLEXITY_OBSERVE', true),\n },\n rateLimit: {\n tiers: resolveTiersFromEnv(),\n keyPrefix: strEnv('VALKEY_KEY_PREFIX', gatewayName),\n observeOnly: boolEnv('RATE_LIMIT_OBSERVE_ONLY', true),\n failClosed: boolEnv('RATE_LIMIT_FAIL_CLOSED', false),\n perWorkspace: {\n // Per-workspace aggregate limiter. observe-only period ended 2026-07-05\n // (2-day bake verified zero normal-usage trips at 6000 req/min budget).\n // Override with RATE_LIMIT_WS_OBSERVE_ONLY=true to revert to measure-only.\n enabled: boolEnv('RATE_LIMIT_WS_ENABLED', true),\n points: intEnv('RATE_LIMIT_WS_POINTS', 6000),\n duration: intEnv('RATE_LIMIT_WS_DURATION', 60),\n burst: intEnv('RATE_LIMIT_WS_BURST', 2000),\n observeOnly: boolEnv('RATE_LIMIT_WS_OBSERVE_ONLY', false),\n },\n },\n operationTimeout: {\n // Default 15s — shorter than the 30s request-limiter queueTimeout, and\n // aligned with typical client-side timeouts so load-shedding fires at\n // the same edge a saturated client would already give up. Mutations\n // that legitimately take longer can override per-deployment via the\n // OPERATION_TIMEOUT_MS env var.\n timeoutMs: intEnv('OPERATION_TIMEOUT_MS', 15000),\n },\n otel: {\n enabled: boolEnv('OTEL_ENABLED', true),\n serviceName: strEnv('OTEL_SERVICE_NAME', gatewayName),\n // Defaults to the collector in this gateway's OWN cluster, derived from\n // the gateway name (`wspace-*` -> otel-collector-wspace, `global-*` ->\n // otel-collector). The previous default,\n // `tempo.tooling.internal.burdenoff.com`, was a retired Azure host and\n // had resolved to nothing since the 2026-08-15 decommission.\n //\n // This is a full signal URL, not a base: OTLPTraceExporter takes `url`\n // verbatim and does not append `/v1/traces` itself.\n endpoint: strEnv('OTEL_EXPORTER_OTLP_ENDPOINT', defaultCollectorTracesEndpoint(gatewayName)),\n environment: strEnv('NODE_ENV', 'development'),\n version: process.env['APP_VERSION'],\n },\n };\n};\n","/**\n * Valkey Client Bootstrap for Gateway Security\n *\n * Wraps the SDK's existing getValkeyClient() (@valkey/valkey-glide) to expose a\n * minimal, stable surface for the rate-limit plugin. Falls back to an\n * in-memory stub so unit tests and local dev without Valkey do not error.\n *\n * @module gateway/security/valkey\n * @category Gateway\n */\n\nimport { logger } from '../../logger/index.js';\nimport type { SecurityValkeyClient } from './types.js';\n\n/**\n * `ioredis` adapter. Used when `VALKEY_CLIENT=ioredis` or as the Bun-compat\n * fallback when `@valkey/valkey-glide` throws at runtime (known issue:\n * `util.Buffer.byteLength` under Bun 1.3.x).\n */\ntype IoRedisInstance = {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, mode?: string, duration?: number): Promise<string | null>;\n incrby(key: string, amount: number): Promise<number>;\n expire(key: string, seconds: number): Promise<number>;\n ttl(key: string): Promise<number>;\n ping(): Promise<string>;\n quit(): Promise<string>;\n on(event: string, listener: (...args: unknown[]) => void): void;\n};\n\nclass IoRedisAdapter implements SecurityValkeyClient {\n constructor(private readonly client: IoRedisInstance) {}\n\n get(key: string): Promise<string | null> {\n return this.client.get(key);\n }\n\n set(key: string, value: string, options?: { EX?: number }): Promise<string | null> {\n if (options?.EX) {\n return this.client.set(key, value, 'EX', options.EX);\n }\n return this.client.set(key, value);\n }\n\n incrBy(key: string, amount: number): Promise<number> {\n return this.client.incrby(key, amount);\n }\n\n async expire(key: string, seconds: number): Promise<boolean> {\n const result = await this.client.expire(key, seconds);\n return result === 1;\n }\n\n ttl(key: string): Promise<number> {\n return this.client.ttl(key);\n }\n\n ping(): Promise<string> {\n return this.client.ping();\n }\n}\n\nconst buildIoRedisClient = async (url: string): Promise<SecurityValkeyClient> => {\n const spec = 'ioredis';\n const mod = (await import(/* @vite-ignore */ spec)) as unknown as {\n default?: new (url: string) => IoRedisInstance;\n Redis?: new (url: string) => IoRedisInstance;\n };\n const Ctor = mod.default ?? mod.Redis;\n if (!Ctor) {\n throw new Error('ioredis module has no Redis constructor');\n }\n const client = new Ctor(url);\n client.on('error', (err) => {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] ioredis error event', { error: e.message });\n });\n return new IoRedisAdapter(client);\n};\n\ntype MemoryEntry = {\n value: string;\n expiresAt: number;\n};\n\n/**\n * Tiny in-memory fallback. Not cross-pod safe; used only when Valkey is\n * absent (e.g., unit tests, local dev without `docker compose up`).\n */\nclass MemoryValkey implements SecurityValkeyClient {\n private store = new Map<string, MemoryEntry>();\n\n private prune(key: string): MemoryEntry | undefined {\n const e = this.store.get(key);\n if (!e) return undefined;\n if (e.expiresAt > 0 && e.expiresAt <= Date.now()) {\n this.store.delete(key);\n return undefined;\n }\n return e;\n }\n\n get(key: string): Promise<string | null> {\n const e = this.prune(key);\n return Promise.resolve(e?.value ?? null);\n }\n\n set(key: string, value: string, options?: { EX?: number }): Promise<string | null> {\n this.store.set(key, {\n value,\n expiresAt: options?.EX ? Date.now() + options.EX * 1000 : 0,\n });\n return Promise.resolve('OK');\n }\n\n incrBy(key: string, amount: number): Promise<number> {\n const e = this.prune(key);\n const next = (e ? parseInt(e.value, 10) || 0 : 0) + amount;\n this.store.set(key, { value: String(next), expiresAt: e?.expiresAt ?? 0 });\n return Promise.resolve(next);\n }\n\n expire(key: string, seconds: number): Promise<boolean> {\n const e = this.store.get(key);\n if (!e) return Promise.resolve(false);\n e.expiresAt = Date.now() + seconds * 1000;\n return Promise.resolve(true);\n }\n\n ttl(key: string): Promise<number> {\n const e = this.prune(key);\n if (!e) return Promise.resolve(-2);\n if (e.expiresAt === 0) return Promise.resolve(-1);\n return Promise.resolve(Math.max(0, Math.ceil((e.expiresAt - Date.now()) / 1000)));\n }\n\n ping(): Promise<string> {\n return Promise.resolve('PONG');\n }\n}\n\nlet singleton: SecurityValkeyClient | null = null;\nlet bootPromise: Promise<SecurityValkeyClient> | null = null;\n\n/**\n * Initialize the Valkey client for the gateway. Reads `VALKEY_URL` (or\n * `REDIS_URL`) + `VALKEY_PASSWORD` from env. On failure: if `VALKEY_REQUIRED`\n * is set to `\"true\"`, throws; otherwise logs a warning and returns the memory\n * fallback so the gateway still boots.\n *\n * Safe to call multiple times — the result is memoized.\n */\nexport const initializeSecurityValkey = async (gatewayName: string): Promise<SecurityValkeyClient> => {\n if (singleton) return singleton;\n if (bootPromise) return bootPromise;\n\n bootPromise = (async (): Promise<SecurityValkeyClient> => {\n const url = process.env['VALKEY_URL'] || process.env['REDIS_URL'];\n const required = process.env['VALKEY_REQUIRED'] === 'true';\n const clientKind = process.env['VALKEY_CLIENT'] ?? 'ioredis';\n\n if (!url) {\n const msg = '[gateway-security] VALKEY_URL not set';\n if (required) throw new Error(`${msg} and VALKEY_REQUIRED=true`);\n logger.warn(`${msg} — using in-memory fallback (not cross-pod safe)`, {\n gatewayName,\n });\n singleton = new MemoryValkey();\n return singleton;\n }\n\n const attempts: Array<{\n kind: string;\n factory: () => Promise<SecurityValkeyClient>;\n }> = [];\n\n if (clientKind === 'ioredis') {\n attempts.push({ kind: 'ioredis', factory: () => buildIoRedisClient(url) });\n attempts.push({\n kind: 'glide (fallback)',\n factory: async () => {\n const { getValkeyClient } = await import('../../cache/index.js');\n return getValkeyClient();\n },\n });\n } else {\n attempts.push({\n kind: 'glide',\n factory: async () => {\n const { getValkeyClient } = await import('../../cache/index.js');\n return getValkeyClient();\n },\n });\n attempts.push({ kind: 'ioredis (fallback)', factory: () => buildIoRedisClient(url) });\n }\n\n let lastError: Error | null = null;\n for (const attempt of attempts) {\n try {\n const client = await attempt.factory();\n const pong = await client.ping();\n if (pong !== 'PONG') {\n throw new Error(`ping returned ${pong}`);\n }\n logger.info('[gateway-security] Valkey connected', {\n gatewayName,\n url,\n client: attempt.kind,\n });\n singleton = client;\n return client;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] Valkey client init failed, will try next', {\n gatewayName,\n client: attempt.kind,\n error: lastError.message,\n });\n }\n }\n\n if (required) {\n logger.error('[gateway-security] Valkey connection failed and required=true', {\n gatewayName,\n error: lastError?.message ?? 'all attempts failed',\n });\n throw lastError ?? new Error('Valkey connection failed');\n }\n logger.warn('[gateway-security] All Valkey clients failed — using in-memory fallback', {\n gatewayName,\n error: lastError?.message ?? 'unknown',\n });\n singleton = new MemoryValkey();\n return singleton;\n })();\n\n return bootPromise;\n};\n\n/**\n * Return the initialized client. Throws if `initializeSecurityValkey` was not\n * called first — keeps the plugin wiring explicit.\n */\nexport const getSecurityValkey = (): SecurityValkeyClient => {\n if (!singleton) {\n throw new Error('[gateway-security] Valkey not initialized — call initializeSecurityValkey() first');\n }\n return singleton;\n};\n\n/**\n * Test-only seam. Replaces the singleton with a stub.\n * Do NOT use in production code.\n */\nexport const __setSecurityValkeyForTest = (client: SecurityValkeyClient | null): void => {\n singleton = client;\n bootPromise = client ? Promise.resolve(client) : null;\n};\n\nexport { MemoryValkey };\n","/**\n * Prometheus Metrics for Gateway Security Plugins\n *\n * Thin wrapper over `prom-client` — optional peer dep. When prom-client is\n * not installed or `PROMETHEUS_METRICS_ENABLED !== 'true'`, every emit is a\n * no-op so the SDK remains consumable without pulling the dependency.\n *\n * Metrics:\n * - `gateway_security_rate_limit_total{gateway,tier,decision}`\n * decision ∈ allowed | rejected | observed_reject\n * - `gateway_security_complexity_rejected_total{gateway,observe}`\n * - `gateway_security_armor_rejected_total{gateway,rule}` (reserved —\n * wiring depends on armor plugin emitting hooks)\n * - `gateway_security_valkey_failover_total{gateway}`\n * - `gateway_security_operation_timeout_total{gateway}`\n *\n * Labels:\n * - `gateway` — gateway name (wspace-public-gateway | global-public-gateway)\n * - `tier` — public | user | app | service | super_admin\n * - `decision` — allowed | rejected | observed_reject\n * - `observe` — 'true' | 'false'\n * - `rule` — armor rule ref (max_aliases, max_tokens, …)\n *\n * All metrics are global singletons across plugin instances. Safe to call\n * `initializeMetrics()` multiple times; subsequent calls are no-ops.\n *\n * @module gateway/security/metrics\n * @category Gateway\n */\n\nimport { logger } from '../../logger/index.js';\n\n// Lightweight type shims for prom-client — keeps this file usable without\n// the peer dep installed.\ntype CounterLike = {\n inc(labels?: Record<string, string>, value?: number): void;\n};\n\ntype CounterCtor = new (opts: { name: string; help: string; labelNames?: string[] }) => CounterLike;\n\ntype PromClientModule = {\n Counter?: CounterCtor;\n register?: { metrics(): Promise<string>; contentType: string };\n};\n\ninterface Metrics {\n rateLimit: CounterLike;\n complexityRejected: CounterLike;\n armorRejected: CounterLike;\n valkeyFailover: CounterLike;\n operationTimeout: CounterLike;\n}\n\nlet metrics: Metrics | null = null;\nlet initializing = false;\nlet promMod: PromClientModule | null = null;\n\nconst noopCounter: CounterLike = {\n inc: () => undefined,\n};\n\nconst noopMetrics: Metrics = {\n rateLimit: noopCounter,\n complexityRejected: noopCounter,\n armorRejected: noopCounter,\n valkeyFailover: noopCounter,\n operationTimeout: noopCounter,\n};\n\n/**\n * Initialize the metrics registry. Safe to call multiple times.\n * Returns a no-op metrics object if prom-client is unavailable.\n */\nexport const initializeMetrics = async (): Promise<Metrics> => {\n if (metrics) return metrics;\n if (initializing) {\n // Another caller is mid-init; return noop to avoid races.\n return noopMetrics;\n }\n if (process.env['PROMETHEUS_METRICS_ENABLED'] !== 'true') {\n logger.info('[gateway-security] Prometheus metrics disabled (PROMETHEUS_METRICS_ENABLED!=true)');\n metrics = noopMetrics;\n return metrics;\n }\n\n initializing = true;\n try {\n const spec = 'prom-client';\n const imported = (await import(/* @vite-ignore */ spec)) as unknown as PromClientModule;\n promMod = imported;\n if (typeof imported.Counter !== 'function') {\n logger.warn('[gateway-security] prom-client has unexpected shape — metrics disabled');\n metrics = noopMetrics;\n return metrics;\n }\n\n const { Counter } = imported;\n metrics = {\n rateLimit: new Counter({\n name: 'gateway_security_rate_limit_total',\n help: 'Rate-limit plugin decisions by tier + gateway',\n labelNames: ['gateway', 'tier', 'decision'],\n }),\n complexityRejected: new Counter({\n name: 'gateway_security_complexity_rejected_total',\n help: 'Query complexity plugin rejections',\n labelNames: ['gateway', 'observe'],\n }),\n armorRejected: new Counter({\n name: 'gateway_security_armor_rejected_total',\n help: 'graphql-armor rule rejections',\n labelNames: ['gateway', 'rule', 'mode'],\n }),\n valkeyFailover: new Counter({\n name: 'gateway_security_valkey_failover_total',\n help: 'Rate-limit plugin fail-open events due to Valkey unreachable',\n labelNames: ['gateway'],\n }),\n operationTimeout: new Counter({\n name: 'gateway_security_operation_timeout_total',\n help: 'Operation timeout plugin aborts',\n labelNames: ['gateway'],\n }),\n };\n logger.info('[gateway-security] Prometheus metrics initialized');\n return metrics;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] prom-client not installed — metrics disabled', {\n error: e.message,\n });\n metrics = noopMetrics;\n return metrics;\n } finally {\n initializing = false;\n }\n};\n\n/**\n * Get the current metrics handle. Returns a noop object if\n * `initializeMetrics()` has not been called or prom-client is unavailable.\n * Always safe to call.\n */\nexport const getMetrics = (): Metrics => metrics ?? noopMetrics;\n\n/**\n * Return the Prometheus registry's default `/metrics` output. Returns\n * `null` if prom-client is not installed.\n */\nexport const scrapeMetrics = async (): Promise<{ body: string; contentType: string } | null> => {\n if (!promMod?.register) return null;\n const body = await promMod.register.metrics();\n return { body, contentType: promMod.register.contentType };\n};\n\n/**\n * Test-only reset. Drops the initialized counters. Do NOT use in production.\n */\nexport const __resetMetricsForTest = (): void => {\n metrics = null;\n initializing = false;\n promMod = null;\n};\n","/**\n * GraphQL Armor Plugin Bundle\n *\n * Wraps the `@escape.tech/graphql-armor-*` validation rules into a single\n * Envelop plugin that runs them inside `onValidate` and sets rejection via\n * `setResult(errors)` — the same pattern that `query-complexity` uses and\n * that Hive Gateway Runtime is confirmed to honor.\n *\n * Why not just use each armor package's own `plugin` factory (which wraps\n * the rule via `addValidationRule`)? Because Hive Gateway Runtime's plugin\n * system does not honor the `addValidationRule` registration path during\n * query validation — rules registered that way are silently dropped. Nor\n * does Hive honor `afterValidate` hooks returned from `onValidate`, which\n * was the first workaround we tried. Only `setResult(errors)` called\n * synchronously inside `onValidate` actually propagates to the client.\n *\n * Rule coverage:\n * - max-aliases (graphql-armor rule)\n * - max-directives (graphql-armor rule)\n * - cost-limit (graphql-armor rule; heuristic pre-pass)\n * - character-limit (implemented inline via `onParse.source.length`\n * because the armor package hooks `onParams` which\n * is not exposed by Envelop — equivalent protection)\n * - block-field-suggestions (still uses the armor plugin — hooks onValidate\n * via `setResult`, which does work)\n * - max-tokens (covered by query-complexity, not re-implemented;\n * token blowup shows up as high cost)\n *\n * In observe mode, rule errors are logged but not attached to the final\n * result — the query proceeds as if nothing happened.\n *\n * @module gateway/security/plugins/armor\n * @category Gateway\n */\n\nimport { GraphQLError, validate as graphqlValidate, type ValidationContext, type ValidationRule } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { getMetrics } from '../metrics.js';\nimport type { ArmorConfig } from '../types.js';\n\ntype RuleFactory = (options: Record<string, unknown>) => ValidationRule;\n\ntype ArmorModule = Record<string, unknown>;\n\nconst tryImport = async (specifier: string): Promise<ArmorModule | null> => {\n try {\n return (await import(specifier)) as ArmorModule;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] armor package not installed — rule skipped', {\n specifier,\n error: e.message,\n });\n return null;\n }\n};\n\nconst pickFactory = (mod: ArmorModule | null, candidates: string[]): RuleFactory | null => {\n if (!mod) return null;\n for (const name of candidates) {\n const fn = mod[name];\n if (typeof fn === 'function') return fn as RuleFactory;\n }\n return null;\n};\n\nconst createMaxAliasesRule = (maxAliases: number): ValidationRule => {\n return (context: ValidationContext) => {\n let aliases = 0;\n\n return {\n Field(node) {\n if (!node.alias) return;\n aliases += 1;\n if (aliases > maxAliases) {\n context.reportError(\n new GraphQLError('Too many field aliases.', {\n nodes: node,\n extensions: { code: 'ARMOR_MAX_ALIASES' },\n })\n );\n }\n },\n };\n };\n};\n\nconst createMaxDirectivesRule = (maxDirectives: number): ValidationRule => {\n return (context: ValidationContext) => {\n let directives = 0;\n\n return {\n Directive(node) {\n directives += 1;\n if (directives > maxDirectives) {\n context.reportError(\n new GraphQLError('Too many directives.', {\n nodes: node,\n extensions: { code: 'ARMOR_MAX_DIRECTIVES' },\n })\n );\n }\n },\n };\n };\n};\n\ninterface LoadedRules {\n maxAliasesRule?: ValidationRule;\n maxDirectivesRule?: ValidationRule;\n costLimitRule?: ValidationRule;\n blockSuggestionsPlugin?: Plugin;\n}\n\n/**\n * When `ARMOR_LEAN=true` (default: false), the gateway loads only the cost-limit\n * rule and skips `max-aliases`, `max-directives`, and `block-field-suggestions`.\n *\n * Rationale: each `@escape.tech/graphql-armor-*` rule runs its own\n * `graphqlValidate(document, [rule])` — a full AST traversal per request. On\n * busy public gateways this shows up as a measurable fraction of total CPU.\n * The cost-limit rule already covers the DoS surface (it rejects expensive\n * aliased-or-deeply-nested queries via the heuristic cost function), and\n * character-limit is handled inline in `onParse`, so the other three rules\n * are refinements rather than load-bearing defences.\n *\n * Opt-in via env so existing services see no behavior change.\n */\nconst isLean = (): boolean => {\n const v = process.env['ARMOR_LEAN'];\n return v === 'true' || v === '1';\n};\n\nconst loadRules = async (cfg: ArmorConfig): Promise<LoadedRules> => {\n const lean = isLean();\n\n const [aliasesMod, directivesMod, costMod, blockSuggestionsMod] = await Promise.all([\n lean ? Promise.resolve(null) : tryImport('@escape.tech/graphql-armor-max-aliases'),\n lean ? Promise.resolve(null) : tryImport('@escape.tech/graphql-armor-max-directives'),\n tryImport('@escape.tech/graphql-armor-cost-limit'),\n lean ? Promise.resolve(null) : tryImport('@escape.tech/graphql-armor-block-field-suggestions'),\n ]);\n\n const loaded: LoadedRules = {};\n\n const maxAliasesFactory = pickFactory(aliasesMod, ['maxAliasesRule']);\n loaded.maxAliasesRule = maxAliasesFactory\n ? maxAliasesFactory({ n: cfg.maxAliases, exposeLimits: cfg.observe })\n : createMaxAliasesRule(cfg.maxAliases);\n\n const maxDirectivesFactory = pickFactory(directivesMod, ['maxDirectivesRule']);\n loaded.maxDirectivesRule = maxDirectivesFactory\n ? maxDirectivesFactory({\n n: cfg.maxDirectives,\n exposeLimits: cfg.observe,\n })\n : createMaxDirectivesRule(cfg.maxDirectives);\n\n const costLimitFactory = pickFactory(costMod, ['costLimitRule']);\n if (costLimitFactory) {\n loaded.costLimitRule = costLimitFactory({\n maxCost: cfg.costLimit,\n objectCost: 2,\n scalarCost: 1,\n depthCostFactor: 1.5,\n ignoreIntrospection: true,\n exposeLimits: cfg.observe,\n });\n }\n\n const blockSuggestionsFactory = pickFactory(blockSuggestionsMod, ['blockFieldSuggestionsPlugin', 'default']);\n if (blockSuggestionsFactory) {\n loaded.blockSuggestionsPlugin = blockSuggestionsFactory({}) as unknown as Plugin;\n }\n\n if (lean) {\n logger.info('[gateway-security] ARMOR_LEAN enabled — running only cost-limit + character-limit', {});\n }\n\n return loaded;\n};\n\n/**\n * Build the Envelop/Yoga plugin list for graphql-armor. Returns the\n * block-field-suggestions plugin (armor's own — this one actually works via\n * `setResult`) plus a custom `onValidate` plugin that runs the rule-based\n * armor checks (max-aliases, max-directives, cost-limit) manually inside\n * `AfterValidate.setResult`.\n *\n * The custom plugin also handles character-limit inline via `onParse`.\n */\nexport const createArmorPlugins = async (cfg: ArmorConfig): Promise<Plugin[]> => {\n const rules = await loadRules(cfg);\n\n const metrics = getMetrics();\n\n // Collect the ValidationRule array once per plugin creation. Envelop's\n // `validateFn` takes an array of rules, but we're bypassing that path and\n // running the rules ourselves inside the afterValidate hook. Each rule is\n // a factory returning a visitor, so this reuse is safe.\n const enabledRules: Array<{ name: string; rule: ValidationRule }> = [];\n if (rules.maxAliasesRule) {\n enabledRules.push({ name: 'max-aliases', rule: rules.maxAliasesRule });\n }\n if (rules.maxDirectivesRule) {\n enabledRules.push({ name: 'max-directives', rule: rules.maxDirectivesRule });\n }\n if (rules.costLimitRule) {\n enabledRules.push({ name: 'cost-limit', rule: rules.costLimitRule });\n }\n\n const armorValidationPlugin: Plugin = {\n onParse({ params }) {\n // Character limit — rejects oversized raw queries before parse even\n // starts. Doing it here is equivalent to graphql-armor-character-limit\n // hooking `onParams`, which is not exposed by Envelop.\n const source = typeof params.source === 'string' ? params.source : params.source?.body;\n if (typeof source === 'string' && source.length > cfg.characterLimit) {\n if (cfg.observe) {\n logger.warn('[gateway-security] armor character-limit exceeded (observe)', {\n length: source.length,\n limit: cfg.characterLimit,\n });\n metrics.armorRejected.inc({ rule: 'character-limit', mode: 'observe' }, 1);\n return;\n }\n metrics.armorRejected.inc({ rule: 'character-limit', mode: 'enforce' }, 1);\n throw new GraphQLError('Syntax Error: Query exceeds maximum character limit.', {\n extensions: {\n code: 'CHARACTER_LIMIT_EXCEEDED',\n http: { status: 400 },\n },\n });\n }\n },\n onValidate({ params, setResult }) {\n if (enabledRules.length === 0) return;\n // Run armor rules manually inside `onValidate`. We initially tried\n // returning an `afterValidate` hook here, but Hive Gateway Runtime\n // silently drops those callbacks — the same class of bug that causes\n // `addValidationRule` not to fire. Doing the work in the synchronous\n // body of `onValidate` + calling `setResult` directly is the pattern\n // that query-complexity uses and it is confirmed to work end-to-end\n // against Hive Gateway.\n //\n // IMPORTANT: graphql-armor rules throw `GraphQLError` synchronously\n // when a limit is exceeded, instead of using the conventional\n // `context.reportError()` path. This propagates as an exception out\n // of `graphqlValidate`, which is why we wrap each rule in an\n // isolated try/catch — otherwise the first throwing rule would hide\n // any subsequent rule failures.\n const armorErrors: GraphQLError[] = [];\n for (const { name, rule } of enabledRules) {\n try {\n const errs = graphqlValidate(params.schema, params.documentAST, [rule]);\n armorErrors.push(...errs);\n } catch (err) {\n // `err instanceof GraphQLError` is NOT reliable here because\n // `@escape.tech/graphql-armor-*` bundles its own copy of\n // `graphql`, so the thrown error's prototype chain does not\n // match the `GraphQLError` class we imported at the top of this\n // file even when both resolve to the same package semver range.\n // We therefore detect armor rule violations by looking at the\n // error shape (either GraphQLError-like or Error-like with a\n // message). Any thrown value from a rule is treated as a\n // violation — rules don't throw for any other reason.\n const message = err instanceof Error ? err.message : String(err);\n const wrapped = new GraphQLError(message, {\n originalError: err instanceof Error ? err : undefined,\n extensions: {\n code: 'ARMOR_VIOLATION',\n rule: name,\n },\n });\n armorErrors.push(wrapped);\n }\n }\n\n if (armorErrors.length === 0) return;\n\n for (const err of armorErrors) {\n logger.warn('[gateway-security] armor rule triggered', {\n message: err.message,\n observe: cfg.observe,\n });\n }\n\n metrics.armorRejected.inc(\n {\n rule: 'armor',\n mode: cfg.observe ? 'observe' : 'enforce',\n },\n armorErrors.length\n );\n\n if (cfg.observe) return;\n\n // Calling `setResult` inside `onValidate` replaces the validation\n // result and skips envelop's own validate invocation. That is exactly\n // what we want — armor violations are fatal, no point running the\n // default graphql-js validation afterwards.\n setResult(armorErrors);\n },\n };\n\n const plugins: Plugin[] = [armorValidationPlugin];\n if (rules.blockSuggestionsPlugin) {\n plugins.push(rules.blockSuggestionsPlugin);\n }\n return plugins;\n};\n","/**\n * Operation Timeout Plugin\n *\n * Races each operation against a configurable timer (default 15s, aligned\n * with typical client-side timeouts and shorter than the 30s request-limiter\n * cap). When the timer fires, the execution errors out with a proper\n * GraphQL error (`OPERATION_TIMEOUT`) rather than the client seeing an\n * abrupt TCP drop.\n *\n * This is implemented via `onExecute` with a promise race — the subgraph\n * fetch already honors AbortController from Yoga, so upstream work is\n * cancelled naturally.\n *\n * @module gateway/security/plugins/operation-timeout\n * @category Gateway\n */\n\nimport { GraphQLError } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\n\nimport type { OperationTimeoutConfig } from '../types.js';\n\nexport interface OperationTimeoutPluginDeps {\n config: OperationTimeoutConfig;\n}\n\ninterface TimerHandle {\n timer: ReturnType<typeof setTimeout>;\n promise: Promise<never>;\n}\n\nconst createTimeoutHandle = (timeoutMs: number, error: GraphQLError): TimerHandle => {\n let timerRef: ReturnType<typeof setTimeout> | undefined;\n const promise = new Promise<never>((_, reject) => {\n timerRef = setTimeout(() => reject(error), timeoutMs);\n });\n return { timer: timerRef as ReturnType<typeof setTimeout>, promise };\n};\n\nexport const createOperationTimeoutPlugin = (deps: OperationTimeoutPluginDeps): Plugin => {\n const timeoutError = new GraphQLError('Operation timeout', {\n extensions: { code: 'OPERATION_TIMEOUT', timeoutMs: deps.config.timeoutMs },\n });\n\n return {\n onExecute: ({ executeFn, setExecuteFn }) => {\n setExecuteFn(async (args) => {\n const handle = createTimeoutHandle(deps.config.timeoutMs, timeoutError);\n try {\n return await Promise.race([executeFn(args), handle.promise]);\n } finally {\n clearTimeout(handle.timer);\n }\n });\n },\n };\n};\n","/**\n * OpenTelemetry Plugin\n *\n * Initializes an OTLP HTTP exporter pointed at Tempo (or any OTLP/HTTP\n * endpoint) and installs `@envelop/opentelemetry` spans around `parse`,\n * `validate`, and `execute`. Imports are dynamic so the SDK stays usable\n * when OTel is disabled or the peer packages are absent.\n *\n * Enrichment: spans carry `gateway.name`, `deployment.environment`, and\n * `service.version` resource attrs. Per-request context (actor, workspace)\n * is propagated via headers because the SDK does not yet wire\n * `propagators` — see the gateway handler edits for `traceparent` forwarding.\n *\n * @module gateway/security/plugins/otel\n * @category Gateway\n */\n\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport type { OtelConfig } from '../types.js';\n\nlet shutdownHook: (() => Promise<void>) | null = null;\n\n// Structural types for the optional OTel peer deps. Constructors accept\n// `unknown` opts because we only need the start/shutdown surface here.\ntype ResourceCtor = new (attrs: Record<string, string>) => unknown;\ntype ResourceFactory = (attrs: Record<string, string>) => unknown;\ntype OtlpExporterCtor = new (opts: { url: string }) => unknown;\ntype NodeSdkInstance = { start(): void; shutdown(): Promise<void> };\ntype NodeSdkCtor = new (opts: { resource: unknown; traceExporter: unknown }) => NodeSdkInstance;\n\ntype ResourceModule = {\n // v1 API\n Resource?: ResourceCtor;\n // v2 API\n resourceFromAttributes?: ResourceFactory;\n};\n\ntype SemanticAttrs = {\n // v1 API\n SemanticResourceAttributes?: {\n SERVICE_NAME: string;\n DEPLOYMENT_ENVIRONMENT: string;\n SERVICE_VERSION: string;\n };\n // v2 API — string constants directly\n ATTR_SERVICE_NAME?: string;\n ATTR_SERVICE_VERSION?: string;\n ATTR_DEPLOYMENT_ENVIRONMENT?: string;\n ATTR_DEPLOYMENT_ENVIRONMENT_NAME?: string;\n};\n\n/**\n * Build an OTel Resource across the v1 → v2 API migration.\n * - v1 (`@opentelemetry/resources` 1.x): `new Resource(attrs)`\n * - v2 (`@opentelemetry/resources` 2.x): `resourceFromAttributes(attrs)`\n */\nconst buildResource = (resMod: ResourceModule, attrs: Record<string, string>): unknown => {\n if (typeof resMod.resourceFromAttributes === 'function') {\n return resMod.resourceFromAttributes(attrs);\n }\n if (typeof resMod.Resource === 'function') {\n return new resMod.Resource(attrs);\n }\n throw new Error('@opentelemetry/resources module exposes neither Resource nor resourceFromAttributes');\n};\n\n/**\n * Resolve semantic attribute keys across the v1 → v2 API migration.\n * - v1: `semcon.SemanticResourceAttributes.SERVICE_NAME` etc.\n * - v2: top-level `ATTR_SERVICE_NAME` string constants. Deployment\n * environment was renamed to `ATTR_DEPLOYMENT_ENVIRONMENT_NAME`.\n */\nconst resolveSemanticKeys = (\n semcon: SemanticAttrs\n): { serviceName: string; deploymentEnv: string; serviceVersion: string } => {\n if (semcon.SemanticResourceAttributes) {\n return {\n serviceName: semcon.SemanticResourceAttributes.SERVICE_NAME,\n deploymentEnv: semcon.SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT,\n serviceVersion: semcon.SemanticResourceAttributes.SERVICE_VERSION,\n };\n }\n return {\n serviceName: semcon.ATTR_SERVICE_NAME ?? 'service.name',\n deploymentEnv:\n semcon.ATTR_DEPLOYMENT_ENVIRONMENT_NAME ?? semcon.ATTR_DEPLOYMENT_ENVIRONMENT ?? 'deployment.environment',\n serviceVersion: semcon.ATTR_SERVICE_VERSION ?? 'service.version',\n };\n};\n\nconst loadOtelPeerDeps = async (): Promise<{\n NodeSDK: NodeSdkCtor;\n OTLPTraceExporter: OtlpExporterCtor;\n resMod: ResourceModule;\n semcon: SemanticAttrs;\n}> => {\n // Optional peer deps — indirect specifiers so TS does not try to resolve.\n const sdkSpec = '@opentelemetry/sdk-node';\n const otlpSpec = '@opentelemetry/exporter-trace-otlp-http';\n const resSpec = '@opentelemetry/resources';\n const semSpec = '@opentelemetry/semantic-conventions';\n const modules = (await Promise.all([\n import(/* @vite-ignore */ sdkSpec),\n import(/* @vite-ignore */ otlpSpec),\n import(/* @vite-ignore */ resSpec),\n import(/* @vite-ignore */ semSpec),\n ])) as [{ NodeSDK: NodeSdkCtor }, { OTLPTraceExporter: OtlpExporterCtor }, ResourceModule, SemanticAttrs];\n const [sdkMod, otlpMod, resMod, semcon] = modules;\n return {\n NodeSDK: sdkMod.NodeSDK,\n OTLPTraceExporter: otlpMod.OTLPTraceExporter,\n resMod,\n semcon,\n };\n};\n\nexport const initializeOtel = async (cfg: OtelConfig): Promise<void> => {\n if (!cfg.enabled) {\n logger.info('[gateway-security] OTel disabled by config');\n return;\n }\n if (shutdownHook) {\n return; // already initialized\n }\n\n try {\n const { NodeSDK, OTLPTraceExporter, resMod, semcon } = await loadOtelPeerDeps();\n const keys = resolveSemanticKeys(semcon);\n\n const resourceAttributes: Record<string, string> = {\n [keys.serviceName]: cfg.serviceName,\n [keys.deploymentEnv]: cfg.environment,\n };\n if (cfg.version) {\n resourceAttributes[keys.serviceVersion] = cfg.version;\n }\n\n const sdk = new NodeSDK({\n resource: buildResource(resMod, resourceAttributes),\n traceExporter: new OTLPTraceExporter({ url: cfg.endpoint }),\n });\n\n sdk.start();\n shutdownHook = (): Promise<void> => sdk.shutdown();\n logger.info('[gateway-security] OTel initialized', {\n serviceName: cfg.serviceName,\n endpoint: cfg.endpoint,\n });\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] OTel init failed — continuing without tracing', {\n error: e.message,\n });\n }\n};\n\nexport const shutdownOtel = async (): Promise<void> => {\n if (shutdownHook) {\n try {\n await shutdownHook();\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] OTel shutdown error', { error: e.message });\n }\n shutdownHook = null;\n }\n};\n\n/**\n * Returns an Envelop plugin that adds spans around parse/validate/execute.\n * Returns an empty plugin when @envelop/opentelemetry is absent.\n */\nexport const createOtelPlugin = async (cfg: OtelConfig): Promise<Plugin> => {\n if (!cfg.enabled) return {};\n try {\n const spec = '@envelop/opentelemetry';\n const mod = (await import(/* @vite-ignore */ spec)) as unknown as {\n useOpenTelemetry?: (opts: {\n spans?: { execute?: boolean; parse?: boolean; validate?: boolean; subscribe?: boolean };\n resolvers?: boolean;\n }) => Plugin;\n };\n if (typeof mod.useOpenTelemetry !== 'function') {\n logger.warn('[gateway-security] @envelop/opentelemetry has unexpected shape — plugin skipped');\n return {};\n }\n return mod.useOpenTelemetry({\n spans: { execute: true, parse: true, validate: true, subscribe: true },\n resolvers: false,\n });\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] @envelop/opentelemetry not installed — plugin skipped', {\n error: e.message,\n });\n return {};\n }\n};\n","/**\n * Query Complexity Plugin\n *\n * Scores each incoming query against a per-field cost map. Scoring happens in\n * the validate phase so rejection is cheap and subgraph fanout is prevented.\n *\n * Observe mode logs the computed cost without rejecting — used during the\n * 48h bake of the hardening pass.\n *\n * @module gateway/security/plugins/query-complexity\n * @category Gateway\n */\n\nimport { GraphQLError, Kind } from 'graphql';\nimport type {\n ArgumentNode,\n FieldNode,\n FragmentDefinitionNode,\n GraphQLSchema,\n OperationDefinitionNode,\n SelectionNode,\n SelectionSetNode,\n ValueNode,\n} from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { getMetrics } from '../metrics.js';\nimport type { CostMap, QueryComplexityConfig } from '../types.js';\n\nconst PAGINATION_ARGUMENTS = new Set(['first', 'limit', 'pageSize']);\nconst MAX_LIST_MULTIPLIER = 100;\nconst MAX_FAILURE_LOG_VARIANTS = 5;\nconst complexityFailureMessages = new Set<string>();\n\ninterface GraphQLNamedTypeLike {\n name?: string;\n getFields?: () => Record<string, GraphQLFieldLike | undefined>;\n}\n\ninterface GraphQLFieldLike {\n name?: string;\n type?: unknown;\n}\n\ninterface GraphQLSchemaLike {\n getQueryType?: () => GraphQLNamedTypeLike | null;\n getMutationType?: () => GraphQLNamedTypeLike | null;\n getSubscriptionType?: () => GraphQLNamedTypeLike | null;\n getType?: (name: string) => GraphQLNamedTypeLike | undefined | null;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null;\n\nconst unwrapNamedType = (type: unknown): GraphQLNamedTypeLike | null => {\n let current = type;\n while (isRecord(current) && current['ofType'] !== undefined) {\n current = current['ofType'];\n }\n return isRecord(current) ? current : null;\n};\n\nconst getSchemaLike = (schema: GraphQLSchema): GraphQLSchemaLike => schema as unknown as GraphQLSchemaLike;\n\nconst getOperationRootType = (\n schema: GraphQLSchema,\n operation: OperationDefinitionNode\n): GraphQLNamedTypeLike | null => {\n const schemaLike = getSchemaLike(schema);\n if (operation.operation === 'mutation') return schemaLike.getMutationType?.() ?? null;\n if (operation.operation === 'subscription') return schemaLike.getSubscriptionType?.() ?? null;\n return schemaLike.getQueryType?.() ?? null;\n};\n\nconst getTypeByName = (schema: GraphQLSchema, name: string): GraphQLNamedTypeLike | null => {\n return getSchemaLike(schema).getType?.(name) ?? null;\n};\n\nconst getField = (parentType: GraphQLNamedTypeLike, fieldName: string): GraphQLFieldLike | undefined => {\n return parentType.getFields?.()[fieldName];\n};\n\nconst getCostMapValue = (costMap: CostMap, parentType: GraphQLNamedTypeLike, fieldName: string): number => {\n if (!parentType.name) return 1;\n return costMap[`${parentType.name}.${fieldName}`] ?? 1;\n};\n\nconst numericValueFromAst = (value: ValueNode): number | undefined => {\n if (value.kind === Kind.INT || value.kind === Kind.FLOAT) {\n const parsed = Number(value.value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n if (value.kind === Kind.STRING) {\n const parsed = Number(value.value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n};\n\nconst listMultiplierFromArgs = (args: readonly ArgumentNode[] | undefined): number => {\n if (!args) return 1;\n for (const arg of args) {\n if (!PAGINATION_ARGUMENTS.has(arg.name.value)) continue;\n const raw = numericValueFromAst(arg.value);\n if (typeof raw !== 'number') return 1;\n return Math.min(Math.max(1, Math.trunc(raw)), MAX_LIST_MULTIPLIER);\n }\n return 1;\n};\n\nconst calculateFieldComplexity = (\n schema: GraphQLSchema,\n fieldNode: FieldNode,\n parentType: GraphQLNamedTypeLike,\n fragments: ReadonlyMap<string, FragmentDefinitionNode>,\n costMap: CostMap,\n activeFragments: Set<string>\n): number => {\n const fieldName = fieldNode.name.value;\n const field = getField(parentType, fieldName);\n const baseCost = getCostMapValue(costMap, parentType, fieldName);\n const namedFieldType = unwrapNamedType(field?.type);\n const childCost =\n fieldNode.selectionSet && namedFieldType\n ? calculateSelectionSetComplexity(\n schema,\n fieldNode.selectionSet,\n namedFieldType,\n fragments,\n costMap,\n activeFragments\n )\n : 0;\n return (baseCost + childCost) * listMultiplierFromArgs(fieldNode.arguments);\n};\n\nconst calculateSelectionSetComplexity = (\n schema: GraphQLSchema,\n selectionSet: SelectionSetNode,\n parentType: GraphQLNamedTypeLike,\n fragments: ReadonlyMap<string, FragmentDefinitionNode>,\n costMap: CostMap,\n activeFragments: Set<string>\n): number => {\n let total = 0;\n\n for (const selection of selectionSet.selections) {\n total += calculateSelectionComplexity(schema, selection, parentType, fragments, costMap, activeFragments);\n }\n\n return total;\n};\n\nconst calculateSelectionComplexity = (\n schema: GraphQLSchema,\n selection: SelectionNode,\n parentType: GraphQLNamedTypeLike,\n fragments: ReadonlyMap<string, FragmentDefinitionNode>,\n costMap: CostMap,\n activeFragments: Set<string>\n): number => {\n if (selection.kind === Kind.FIELD) {\n return calculateFieldComplexity(schema, selection, parentType, fragments, costMap, activeFragments);\n }\n\n if (selection.kind === Kind.INLINE_FRAGMENT) {\n const fragmentParent = selection.typeCondition\n ? (getTypeByName(schema, selection.typeCondition.name.value) ?? parentType)\n : parentType;\n return calculateSelectionSetComplexity(\n schema,\n selection.selectionSet,\n fragmentParent,\n fragments,\n costMap,\n activeFragments\n );\n }\n\n const fragmentName = selection.name.value;\n if (activeFragments.has(fragmentName)) return 0;\n const fragment = fragments.get(fragmentName);\n if (!fragment) return 0;\n\n activeFragments.add(fragmentName);\n const fragmentParent = getTypeByName(schema, fragment.typeCondition.name.value) ?? parentType;\n const complexity = calculateSelectionSetComplexity(\n schema,\n fragment.selectionSet,\n fragmentParent,\n fragments,\n costMap,\n activeFragments\n );\n activeFragments.delete(fragmentName);\n return complexity;\n};\n\nconst calculateDocumentComplexity = (\n schema: GraphQLSchema,\n documentAST: { definitions: readonly unknown[] },\n costMap: CostMap\n): number => {\n const fragments = new Map<string, FragmentDefinitionNode>();\n const operations: OperationDefinitionNode[] = [];\n\n for (const definition of documentAST.definitions) {\n if (!isRecord(definition) || typeof definition['kind'] !== 'string') continue;\n if (definition['kind'] === Kind.FRAGMENT_DEFINITION) {\n const fragment = definition as unknown as FragmentDefinitionNode;\n fragments.set(fragment.name.value, fragment);\n } else if (definition['kind'] === Kind.OPERATION_DEFINITION) {\n operations.push(definition as unknown as OperationDefinitionNode);\n }\n }\n\n let maxComplexity = 0;\n for (const operation of operations) {\n const rootType = getOperationRootType(schema, operation);\n if (!rootType) continue;\n const complexity = calculateSelectionSetComplexity(\n schema,\n operation.selectionSet,\n rootType,\n fragments,\n costMap,\n new Set<string>()\n );\n maxComplexity = Math.max(maxComplexity, complexity);\n }\n\n return maxComplexity;\n};\n\nconst logComplexityFailure = (error: Error): void => {\n const seen = complexityFailureMessages.has(error.message);\n if (!seen && complexityFailureMessages.size < MAX_FAILURE_LOG_VARIANTS) {\n complexityFailureMessages.add(error.message);\n logger.warn('[gateway-security] complexity scoring failed — fail-open', {\n error: error.message,\n suppressedRepeats: true,\n });\n return;\n }\n\n logger.debug('[gateway-security] repeated complexity scoring failure suppressed', {\n error: error.message,\n });\n};\n\nexport interface QueryComplexityPluginDeps {\n config: QueryComplexityConfig;\n}\n\nexport const createQueryComplexityPlugin = (deps: QueryComplexityPluginDeps): Plugin => {\n return {\n onValidate: ({ params, setResult }) => {\n try {\n const complexity = calculateDocumentComplexity(params.schema, params.documentAST, deps.config.costMap);\n\n if (complexity > deps.config.maxCost) {\n getMetrics().complexityRejected.inc({\n gateway: 'unknown',\n observe: deps.config.observe ? 'true' : 'false',\n });\n if (deps.config.observe) {\n logger.info('[gateway-security] complexity would_reject (observe)', {\n complexity,\n maxCost: deps.config.maxCost,\n });\n return;\n }\n setResult([\n new GraphQLError(`Query too expensive (cost ${complexity} > limit ${deps.config.maxCost})`, {\n extensions: {\n code: 'COMPLEXITY_TOO_HIGH',\n cost: complexity,\n maxCost: deps.config.maxCost,\n },\n }),\n ]);\n }\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logComplexityFailure(e);\n }\n },\n };\n};\n","/**\n * Rate-Limit Plugin\n *\n * Per-actor token-bucket rate limiter backed by Valkey. Tier classification\n * from ActorContext. Increments a counter with a window-scoped TTL and\n * rejects when the bucket is exhausted. Emits rate-limit response headers\n * on every request (X-RateLimit-Limit / Remaining / Reset).\n *\n * Failure policy: **fail open** by default (availability > strictness during\n * Valkey outages). Flip with `failClosed: true`.\n *\n * Observe mode: when `observeOnly: true`, counts and logs but never rejects.\n * Used during the 48h bake of this hardening pass.\n *\n * @module gateway/security/plugins/rate-limit\n * @category Gateway\n */\n\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { resolveActor } from '../actor.js';\nimport { getMetrics } from '../metrics.js';\nimport type { ActorContext, RateLimitConfig, RateLimitResult, SecurityValkeyClient } from '../types.js';\n\nexport interface RateLimitPluginDeps {\n valkey: SecurityValkeyClient;\n config: RateLimitConfig;\n}\n\nconst keyFor = (prefix: string, tier: string, identity: string): string => `rl:${prefix}:${tier}:${identity}`;\n\nconst wsKeyFor = (prefix: string, workspaceId: string): string => `rl:${prefix}:ws:${workspaceId}`;\n\nconst stamp = (): number => Date.now();\n\n/**\n * Atomic-ish INCR + EXPIRE. Valkey does not guarantee atomicity between the\n * two without a Lua script; the race window here loses at most 1 event per\n * window-start collision, which is acceptable for a limiter and avoids the\n * Lua script registration dance.\n */\nexport const checkRateLimit = async (deps: RateLimitPluginDeps, actor: ActorContext): Promise<RateLimitResult> => {\n const tier = deps.config.tiers[actor.tier];\n const metrics = getMetrics();\n const gateway = deps.config.keyPrefix;\n // Super admin passes through.\n if (tier.points === Number.MAX_SAFE_INTEGER) {\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'allowed' });\n return { allowed: true, remaining: Number.MAX_SAFE_INTEGER, resetAtMs: 0, limit: tier.points };\n }\n\n const key = keyFor(deps.config.keyPrefix, actor.tier, actor.identity);\n const limit = tier.points + tier.burst;\n\n try {\n const count = await deps.valkey.incrBy(key, 1);\n if (count === 1) {\n await deps.valkey.expire(key, tier.duration);\n }\n const ttl = await deps.valkey.ttl(key);\n const resetAtMs = stamp() + Math.max(0, ttl) * 1000;\n\n if (count > limit) {\n metrics.rateLimit.inc({\n gateway,\n tier: actor.tier,\n decision: deps.config.observeOnly ? 'observed_reject' : 'rejected',\n });\n return { allowed: false, remaining: 0, resetAtMs, limit };\n }\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'allowed' });\n return { allowed: true, remaining: Math.max(0, limit - count), resetAtMs, limit };\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] rate-limit valkey error — fail-open', {\n key,\n error: e.message,\n });\n metrics.valkeyFailover.inc({ gateway });\n if (deps.config.failClosed) {\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'rejected' });\n return { allowed: false, remaining: 0, resetAtMs: stamp() + tier.duration * 1000, limit };\n }\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'allowed' });\n return { allowed: true, remaining: -1, resetAtMs: 0, limit };\n }\n};\n\n/**\n * Per-workspace AGGREGATE rate limit. The per-actor limiter (checkRateLimit)\n * caps each user; this caps the whole workspace so that N users in one workspace\n * cannot collectively starve other workspaces on the shared backend. Runs only\n * when a workspaceId is present. Emits the decision under `tier: 'workspace'`\n * (workspaceId is logged, NOT a metric label, to avoid metric cardinality\n * blow-up). Always fails OPEN on a Valkey error — a fairness signal must never be\n * an availability dependency.\n */\nexport const checkWorkspaceRateLimit = async (\n deps: RateLimitPluginDeps,\n workspaceId: string\n): Promise<RateLimitResult> => {\n const cfg = deps.config.perWorkspace;\n const metrics = getMetrics();\n const gateway = deps.config.keyPrefix;\n const key = wsKeyFor(deps.config.keyPrefix, workspaceId);\n const limit = cfg.points + cfg.burst;\n\n try {\n const count = await deps.valkey.incrBy(key, 1);\n if (count === 1) {\n await deps.valkey.expire(key, cfg.duration);\n }\n const ttl = await deps.valkey.ttl(key);\n const resetAtMs = stamp() + Math.max(0, ttl) * 1000;\n\n if (count > limit) {\n metrics.rateLimit.inc({\n gateway,\n tier: 'workspace',\n decision: cfg.observeOnly ? 'observed_reject' : 'rejected',\n });\n // workspaceId in the LOG (not a metric label) → noisy-neighbor leaderboard\n logger.warn('[gateway-security] workspace rate-limit exceeded', {\n workspaceId,\n count,\n limit,\n observe: cfg.observeOnly,\n });\n return { allowed: false, remaining: 0, resetAtMs, limit };\n }\n metrics.rateLimit.inc({ gateway, tier: 'workspace', decision: 'allowed' });\n return { allowed: true, remaining: Math.max(0, limit - count), resetAtMs, limit };\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] workspace rate-limit valkey error — fail-open', {\n key,\n error: e.message,\n });\n metrics.valkeyFailover.inc({ gateway });\n return { allowed: true, remaining: -1, resetAtMs: 0, limit };\n }\n};\n\n/**\n * Yoga/Envelop plugin factory.\n */\nexport const createRateLimitPlugin = (deps: RateLimitPluginDeps): Plugin => {\n return {\n onRequest: async ({ request, fetchAPI, endResponse }): Promise<void> => {\n const actor = resolveActor((name) => request.headers.get(name));\n const result = await checkRateLimit(deps, actor);\n\n // Headers are set via onResponse (below). Stash the result on the request\n // so onResponse can read it without re-running the Valkey call.\n (request as unknown as { __rateLimitResult: RateLimitResult; __rateLimitActor: ActorContext }).__rateLimitResult =\n result;\n (request as unknown as { __rateLimitResult: RateLimitResult; __rateLimitActor: ActorContext }).__rateLimitActor =\n actor;\n\n // Per-workspace aggregate limiter (fairness). Independent of the per-actor\n // bucket: measures the whole workspace's request rate so one workspace's\n // many users can't collectively starve others. Observe-only by default →\n // it records + logs but does not reject; enforcement is opt-in.\n const workspaceId = actor.headers.workspaceId;\n if (deps.config.perWorkspace.enabled && workspaceId) {\n const wsResult = await checkWorkspaceRateLimit(deps, workspaceId);\n if (!wsResult.allowed && !deps.config.perWorkspace.observeOnly) {\n const retryAfterS = Math.max(1, Math.ceil((wsResult.resetAtMs - stamp()) / 1000));\n const body = JSON.stringify({\n errors: [\n {\n message: 'Workspace rate limit exceeded',\n extensions: {\n code: 'RATE_LIMITED',\n scope: 'workspace',\n resetAt: new Date(wsResult.resetAtMs).toISOString(),\n },\n },\n ],\n });\n endResponse(\n new fetchAPI.Response(body, {\n status: 429,\n headers: {\n 'content-type': 'application/json',\n 'retry-after': String(retryAfterS),\n 'x-ratelimit-scope': 'workspace',\n 'x-ratelimit-limit': String(wsResult.limit),\n 'x-ratelimit-remaining': '0',\n 'x-ratelimit-reset': String(Math.floor(wsResult.resetAtMs / 1000)),\n },\n })\n );\n return;\n }\n }\n\n if (!result.allowed) {\n if (deps.config.observeOnly) {\n logger.info('[gateway-security] rate-limit would_reject (observe)', {\n tier: actor.tier,\n identity: actor.identity,\n limit: result.limit,\n });\n return;\n }\n const retryAfterS = Math.max(1, Math.ceil((result.resetAtMs - stamp()) / 1000));\n const body = JSON.stringify({\n errors: [\n {\n message: 'Rate limit exceeded',\n extensions: {\n code: 'RATE_LIMITED',\n resetAt: new Date(result.resetAtMs).toISOString(),\n },\n },\n ],\n });\n const response = new fetchAPI.Response(body, {\n status: 429,\n headers: {\n 'content-type': 'application/json',\n 'retry-after': String(retryAfterS),\n 'x-ratelimit-limit': String(result.limit),\n 'x-ratelimit-remaining': '0',\n 'x-ratelimit-reset': String(Math.floor(result.resetAtMs / 1000)),\n },\n });\n endResponse(response);\n }\n },\n onResponse: ({ request, response }): void => {\n const stash = (request as unknown as { __rateLimitResult?: RateLimitResult }).__rateLimitResult;\n if (!stash) return;\n response.headers.set('x-ratelimit-limit', String(stash.limit));\n response.headers.set('x-ratelimit-remaining', String(Math.max(0, stash.remaining)));\n if (stash.resetAtMs > 0) {\n response.headers.set('x-ratelimit-reset', String(Math.floor(stash.resetAtMs / 1000)));\n }\n },\n };\n};\n","/**\n * Gateway Security Plugin Orchestrator\n *\n * Builds the ordered Yoga/Envelop plugin array consumed by each public\n * gateway via `createGatewayRuntime({ plugins: [...] })`.\n *\n * Order (cheapest rejection first, span wrapping everything):\n * otel spans → armor (6 sub-plugins) → query-complexity → rate-limit → timeout\n *\n * @module gateway/security/plugins\n * @category Gateway\n */\n\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { initializeMetrics } from '../metrics.js';\nimport type { GatewaySecurityOptions } from '../types.js';\nimport { initializeSecurityValkey } from '../valkey.js';\nimport { createArmorPlugins } from './armor.js';\nimport { createOperationTimeoutPlugin } from './operation-timeout.js';\nimport { createOtelPlugin } from './otel.js';\nimport { createQueryComplexityPlugin } from './query-complexity.js';\nimport { createRateLimitPlugin } from './rate-limit.js';\n\n/**\n * Bootstraps Valkey + OTel side effects and returns the ordered plugin list.\n * Safe to call once at gateway boot; subsequent calls reuse the initialized\n * singletons.\n *\n * If `options.enabled === false`, returns an empty array — the master kill\n * switch for instant rollback via env flag.\n */\nexport const buildSecurityPlugins = async (options: GatewaySecurityOptions): Promise<Plugin[]> => {\n if (!options.enabled) {\n logger.warn('[gateway-security] SECURITY_PLUGINS_ENABLED=false — plugins disabled', {\n gatewayName: options.gatewayName,\n });\n return [];\n }\n\n // Side-effect init (both are idempotent). OTel exporter bootstrap belongs to\n // `bootstrapTelemetry()`; this stack only wires Envelop span hooks.\n await initializeMetrics();\n const valkey = await initializeSecurityValkey(options.gatewayName);\n\n const plugins: Plugin[] = [];\n\n const otelPlugin = await createOtelPlugin(options.otel);\n plugins.push(otelPlugin);\n\n const armorPlugins = await createArmorPlugins(options.armor);\n plugins.push(...armorPlugins);\n\n if (options.queryComplexity.enabled) {\n plugins.push(createQueryComplexityPlugin({ config: options.queryComplexity }));\n }\n plugins.push(createRateLimitPlugin({ valkey, config: options.rateLimit }));\n plugins.push(createOperationTimeoutPlugin({ config: options.operationTimeout }));\n\n logger.info('[gateway-security] plugins wired', {\n gatewayName: options.gatewayName,\n count: plugins.length,\n observe: {\n armor: options.armor.observe,\n complexity: options.queryComplexity.observe,\n rateLimit: options.rateLimit.observeOnly,\n },\n enabled: {\n complexity: options.queryComplexity.enabled,\n },\n });\n\n return plugins;\n};\n\nexport { createArmorPlugins } from './armor.js';\nexport { createOperationTimeoutPlugin } from './operation-timeout.js';\nexport { createOtelPlugin, initializeOtel, shutdownOtel } from './otel.js';\nexport { createQueryComplexityPlugin } from './query-complexity.js';\nexport { checkRateLimit, createRateLimitPlugin } from './rate-limit.js';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/gateway/security/index.ts","../src/gateway/security/actor.ts","../src/gateway/security/cost-map.ts","../src/gateway/security/tiers.ts","../src/gateway/security/defaults.ts","../src/gateway/security/valkey.ts","../src/gateway/security/metrics.ts","../src/gateway/security/plugins/armor.ts","../src/gateway/security/plugins/operation-timeout.ts","../src/gateway/security/plugins/otel.ts","../src/gateway/security/plugins/query-complexity.ts","../src/gateway/security/plugins/rate-limit.ts","../src/gateway/security/plugins/index.ts"],"names":["firstIp","header","undefined","split","trim","classify","actorType","actorRole","resolveActor","getHeader","actorId","workspaceId","tenantId","orgId","appId","ip","tier","identity","headers","DEFAULT_COST_MAP","mergeCostMap","base","override","DEFAULT_TIERS","public","points","duration","burst","user","app","service","super_admin","Number","MAX_SAFE_INTEGER","positiveInt","value","fallback","parsed","parseInt","isFinite","resolveTiersFromEnv","out","Object","keys","forEach","upper","toUpperCase","process","env","boolEnv","key","v","intEnv","strEnv","DEFAULT_ARMOR_CONFIG","maxAliases","maxTokens","maxDirectives","characterLimit","costLimit","observe","resolveSecurityOptionsFromEnv","gatewayName","costMapOverride","enabled","armor","queryComplexity","maxCost","costMap","rateLimit","tiers","keyPrefix","observeOnly","failClosed","perWorkspace","operationTimeout","timeoutMs","otel","serviceName","endpoint","defaultCollectorTracesEndpoint","environment","version","IoRedisAdapter","client","get","set","options","EX","incrBy","amount","incrby","expire","seconds","result","ttl","ping","buildIoRedisClient","url","spec","mod","Ctor","default","Redis","Error","on","err","e","String","logger","warn","error","message","MemoryValkey","store","Map","prune","expiresAt","Date","now","delete","Promise","resolve","next","Math","max","ceil","singleton","bootPromise","initializeSecurityValkey","required","clientKind","msg","attempts","push","kind","factory","getValkeyClient","lastError","attempt","pong","info","getSecurityValkey","__setSecurityValkeyForTest","metrics","initializing","promMod","noopCounter","inc","noopMetrics","complexityRejected","armorRejected","valkeyFailover","initializeMetrics","imported","Counter","name","help","labelNames","getMetrics","scrapeMetrics","register","body","contentType","__resetMetricsForTest","tryImport","specifier","pickFactory","candidates","fn","createMaxAliasesRule","context","aliases","Field","node","alias","reportError","GraphQLError","nodes","extensions","code","createMaxDirectivesRule","directives","Directive","isLean","loadRules","cfg","lean","aliasesMod","directivesMod","costMod","blockSuggestionsMod","all","loaded","maxAliasesFactory","maxAliasesRule","n","exposeLimits","maxDirectivesFactory","maxDirectivesRule","costLimitFactory","costLimitRule","objectCost","scalarCost","depthCostFactor","ignoreIntrospection","blockSuggestionsFactory","blockSuggestionsPlugin","createArmorPlugins","rules","enabledRules","rule","armorValidationPlugin","onParse","params","source","length","limit","mode","http","status","onValidate","setResult","armorErrors","errs","graphqlValidate","schema","documentAST","wrapped","originalError","plugins","createTimeoutHandle","timerRef","promise","_","reject","setTimeout","timer","createOperationTimeoutPlugin","deps","timeoutError","config","onExecute","executeFn","setExecuteFn","args","handle","race","clearTimeout","shutdownHook","buildResource","resMod","attrs","resourceFromAttributes","Resource","resolveSemanticKeys","semcon","SemanticResourceAttributes","SERVICE_NAME","deploymentEnv","DEPLOYMENT_ENVIRONMENT","serviceVersion","SERVICE_VERSION","ATTR_SERVICE_NAME","ATTR_DEPLOYMENT_ENVIRONMENT_NAME","ATTR_DEPLOYMENT_ENVIRONMENT","ATTR_SERVICE_VERSION","loadOtelPeerDeps","sdkSpec","otlpSpec","resSpec","semSpec","modules","sdkMod","otlpMod","NodeSDK","OTLPTraceExporter","initializeOtel","resourceAttributes","sdk","resource","traceExporter","start","shutdown","shutdownOtel","createOtelPlugin","useOpenTelemetry","spans","execute","parse","validate","subscribe","resolvers","PAGINATION_ARGUMENTS","Set","MAX_LIST_MULTIPLIER","MAX_FAILURE_LOG_VARIANTS","complexityFailureMessages","isRecord","unwrapNamedType","type","current","getSchemaLike","getOperationRootType","operation","schemaLike","getMutationType","getSubscriptionType","getQueryType","getTypeByName","getType","getField","parentType","fieldName","getFields","getCostMapValue","numericValueFromAst","Kind","INT","FLOAT","STRING","listMultiplierFromArgs","arg","has","raw","min","trunc","calculateFieldComplexity","fieldNode","fragments","activeFragments","field","baseCost","namedFieldType","childCost","selectionSet","calculateSelectionSetComplexity","arguments","total","selection","selections","calculateSelectionComplexity","FIELD","INLINE_FRAGMENT","fragmentParent","typeCondition","fragmentName","fragment","add","complexity","calculateDocumentComplexity","operations","definition","definitions","FRAGMENT_DEFINITION","OPERATION_DEFINITION","maxComplexity","rootType","logComplexityFailure","seen","size","suppressedRepeats","debug","createQueryComplexityPlugin","gateway","cost","keyFor","prefix","wsKeyFor","stamp","checkRateLimit","actor","decision","allowed","remaining","resetAtMs","count","valkey","checkWorkspaceRateLimit","createRateLimitPlugin","onRequest","request","fetchAPI","endResponse","__rateLimitResult","__rateLimitActor","wsResult","retryAfterS","JSON","stringify","errors","scope","resetAt","toISOString","Response","floor","response","onResponse","stash","buildSecurityPlugins","otelPlugin","armorPlugins"],"mappings":"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","file":"chunk-NVVWSOY7.js","sourcesContent":["/**\n * Gateway Security Module — public API\n *\n * Plug-in stack for public GraphQL federation gateways:\n * graphql-armor, per-field query complexity, per-actor rate limiting,\n * operation-level AbortController, OpenTelemetry spans.\n *\n * Consumed by each public gateway via:\n * ```ts\n * import { buildSecurityPlugins, resolveSecurityOptionsFromEnv } from '@burdenoff/be-sdk/gateway/security';\n *\n * const plugins = await buildSecurityPlugins(\n * resolveSecurityOptionsFromEnv('wspace-public-gateway', { 'Query.customField': 100 })\n * );\n * // pass plugins into createGatewayRuntime({ plugins })\n * ```\n *\n * @module gateway/security\n * @category Gateway\n */\n\nexport { resolveActor } from './actor.js';\nexport { DEFAULT_COST_MAP, mergeCostMap } from './cost-map.js';\nexport { DEFAULT_ARMOR_CONFIG, resolveSecurityOptionsFromEnv } from './defaults.js';\nexport { DEFAULT_TIERS, resolveTiersFromEnv } from './tiers.js';\nexport type {\n ActorContext,\n ArmorConfig,\n CostMap,\n GatewaySecurityOptions,\n OperationTimeoutConfig,\n OtelConfig,\n QueryComplexityConfig,\n RateLimitConfig,\n RateLimitResult,\n SecurityValkeyClient,\n Tier,\n TierLimits,\n} from './types.js';\nexport { __setSecurityValkeyForTest, getSecurityValkey, initializeSecurityValkey, MemoryValkey } from './valkey.js';\nexport { __resetMetricsForTest, getMetrics, initializeMetrics, scrapeMetrics } from './metrics.js';\n\nexport {\n buildSecurityPlugins,\n createArmorPlugins,\n createOperationTimeoutPlugin,\n createOtelPlugin,\n createQueryComplexityPlugin,\n createRateLimitPlugin,\n checkRateLimit,\n initializeOtel,\n shutdownOtel,\n} from './plugins/index.js';\n","/**\n * Actor Resolver\n *\n * Derives an ActorContext from the headers that the gateway's auth middleware\n * already injects (`x-actor-*`, `x-workspace-id`, `x-tenant-id`, `x-org-id`,\n * `x-forwarded-for`). This is the identity used for rate-limit buckets and\n * OTel span enrichment.\n *\n * @module gateway/security/actor\n * @category Gateway\n */\n\nimport type { ActorContext, Tier } from './types.js';\n\ntype HeaderGetter = (name: string) => string | null | undefined;\n\nconst firstIp = (header: string | null | undefined): string | undefined => {\n if (!header) return undefined;\n // x-forwarded-for is a comma-separated list; take the left-most (client).\n return header.split(',')[0]?.trim() || undefined;\n};\n\nconst classify = (actorType: string | undefined, actorRole: string | undefined): Tier => {\n if (actorRole === 'super_admin') return 'super_admin';\n switch (actorType) {\n case 'user':\n return 'user';\n case 'app':\n return 'app';\n case 'service':\n case 'service_account':\n return 'service';\n case 'super_admin':\n return 'super_admin';\n default:\n return 'public';\n }\n};\n\n/**\n * Resolve the canonical ActorContext for a request.\n * Accepts a `HeaderGetter` so it is trivially testable with a plain function.\n */\nexport const resolveActor = (getHeader: HeaderGetter): ActorContext => {\n const actorId = getHeader('x-actor-id') ?? undefined;\n const actorType = getHeader('x-actor-type') ?? undefined;\n const actorRole = getHeader('x-actor-role') ?? undefined;\n const workspaceId = getHeader('x-workspace-id') ?? undefined;\n const tenantId = getHeader('x-tenant-id') ?? undefined;\n const orgId = getHeader('x-org-id') ?? undefined;\n const appId = getHeader('x-app-id') ?? undefined;\n const ip =\n firstIp(getHeader('x-forwarded-for')) || getHeader('x-real-ip') || getHeader('cf-connecting-ip') || undefined;\n\n const tier = classify(actorType, actorRole);\n\n let identity: string;\n switch (tier) {\n case 'super_admin':\n identity = 'bypass';\n break;\n case 'service':\n identity = `svc:${actorId ?? 'unknown'}`;\n break;\n case 'app':\n identity = `${tenantId ?? 'notenant'}:${appId ?? actorId ?? 'unknown'}`;\n break;\n case 'user':\n identity = `${workspaceId ?? 'nows'}:${actorId ?? 'unknown'}`;\n break;\n case 'public':\n default:\n identity = `ip:${ip ?? 'unknown'}`;\n }\n\n return {\n tier,\n identity,\n headers: {\n actorId,\n actorType,\n actorRole,\n workspaceId,\n tenantId,\n orgId,\n appId,\n ip,\n },\n };\n};\n","/**\n * Default query complexity cost map.\n *\n * Key format: \"TypeName.fieldName\". Values are base costs. List fields multiply\n * by the requested page size (up to 100) via the plugin's list-multiplier.\n *\n * Seeded from known high-cost queries across the Burdenoff federation:\n * search, analytics, reports, enumerations, introspection.\n *\n * Extend via `mergeCostMap(DEFAULT_COST_MAP, override)` in each gateway.\n *\n * @module gateway/security/cost-map\n * @category Gateway\n */\n\nimport type { CostMap } from './types.js';\n\nexport const DEFAULT_COST_MAP: CostMap = {\n // Cross-subgraph search — fanout\n 'Query.searchBigConsole': 200,\n 'Query.searchWorkspaces': 100,\n 'Query.searchTags': 80,\n\n // Aggregations\n 'Query.analyticsReport': 300,\n 'Query.usageReport': 250,\n 'Query.billingReport': 250,\n 'Query.auditLog': 150,\n\n // Enumeration risk (paginated lists)\n 'Query.listUsers': 50,\n 'Query.listWorkspaces': 50,\n 'Query.listFiles': 40,\n 'Query.listTags': 20,\n 'Query.listApps': 40,\n\n // Nested lists\n 'Workspace.members': 5,\n 'User.workspaces': 10,\n 'User.apps': 5,\n 'Tag.appliedTo': 5,\n\n // Introspection — expensive and abuse-prone in prod\n 'Query.__schema': 1000,\n 'Query.__type': 500,\n\n // Heavy writers\n 'Mutation.bulkImport': 500,\n 'Mutation.webhookTrigger': 100,\n};\n\nexport const mergeCostMap = (base: CostMap, override: CostMap): CostMap => ({\n ...base,\n ...override,\n});\n","/**\n * Default rate-limit tiers for public gateways.\n *\n * These defaults target a single pod; cross-pod fairness is provided by the\n * Valkey-backed counter. Tune via `GATEWAY_RATE_LIMIT_*` env vars.\n *\n * @module gateway/security/tiers\n * @category Gateway\n */\n\nimport type { Tier, TierLimits } from './types.js';\n\nexport const DEFAULT_TIERS: Record<Tier, TierLimits> = {\n // Public (anonymous) traffic is keyed per-IP. The previous 60+20=80/60s\n // ceiling (1.33 req/s sustained) was tight enough that a single heavy\n // frontend page load (≈15–30 GraphQL queries) plus a NAT-shared second\n // user could blow the bucket on benign traffic. Bumping to 120+60=180/60s\n // (3 req/s sustained) gives 2× headroom while staying ~40× below the\n // ~130 req/s single-pod compute floor measured under realistic load.\n public: {\n points: 120,\n duration: 60,\n burst: 60,\n },\n user: {\n points: 600,\n duration: 60,\n burst: 120,\n },\n app: {\n points: 3000,\n duration: 60,\n burst: 500,\n },\n service: {\n points: 6000,\n duration: 60,\n burst: 1000,\n },\n super_admin: {\n points: Number.MAX_SAFE_INTEGER,\n duration: 60,\n burst: Number.MAX_SAFE_INTEGER,\n },\n};\n\nconst positiveInt = (value: string | undefined, fallback: number): number => {\n if (!value) return fallback;\n const parsed = parseInt(value, 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n};\n\n/**\n * Read tier overrides from env.\n *\n * Env var pattern: `GATEWAY_RL_{TIER}_{POINTS|DURATION|BURST}`\n * Example: `GATEWAY_RL_USER_POINTS=1200`\n */\nexport const resolveTiersFromEnv = (base: Record<Tier, TierLimits> = DEFAULT_TIERS): Record<Tier, TierLimits> => {\n const out: Record<Tier, TierLimits> = { ...base };\n (Object.keys(base) as Tier[]).forEach((tier) => {\n const upper = tier.toUpperCase();\n out[tier] = {\n points: positiveInt(process.env[`GATEWAY_RL_${upper}_POINTS`], base[tier].points),\n duration: positiveInt(process.env[`GATEWAY_RL_${upper}_DURATION`], base[tier].duration),\n burst: positiveInt(process.env[`GATEWAY_RL_${upper}_BURST`], base[tier].burst),\n };\n });\n return out;\n};\n","/**\n * Gateway Security Defaults\n *\n * Production-safe defaults for the security plugin stack, and helpers to\n * assemble `GatewaySecurityOptions` from environment variables. Each field\n * honors an `*_OBSERVE*` flag so the hardening pass can soft-launch\n * observe-only before flipping to enforce.\n *\n * @module gateway/security/defaults\n * @category Gateway\n */\n\nimport { defaultCollectorTracesEndpoint } from '../../telemetry/collector-endpoint.js';\nimport { DEFAULT_COST_MAP, mergeCostMap } from './cost-map.js';\nimport { resolveTiersFromEnv } from './tiers.js';\nimport type { ArmorConfig, CostMap, GatewaySecurityOptions } from './types.js';\n\nconst boolEnv = (key: string, fallback: boolean): boolean => {\n const v = process.env[key];\n if (v === undefined) return fallback;\n return v === 'true' || v === '1';\n};\n\nconst intEnv = (key: string, fallback: number): number => {\n const v = process.env[key];\n if (!v) return fallback;\n const parsed = parseInt(v, 10);\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst strEnv = (key: string, fallback: string): string => process.env[key] ?? fallback;\n\n/**\n * Default armor thresholds for public gateways.\n */\nexport const DEFAULT_ARMOR_CONFIG: ArmorConfig = {\n maxAliases: 15,\n maxTokens: 1000,\n maxDirectives: 50,\n characterLimit: 15000,\n costLimit: 5000,\n observe: true,\n};\n\n/**\n * Build `GatewaySecurityOptions` by reading env vars.\n *\n * All defaults are production-safe but begin in observe-only mode so the\n * first deploy does not reject any traffic. Flip observe flags to `false`\n * after the 48h bake.\n */\nexport const resolveSecurityOptionsFromEnv = (\n gatewayName: string,\n costMapOverride?: CostMap\n): GatewaySecurityOptions => {\n return {\n gatewayName,\n enabled: boolEnv('SECURITY_PLUGINS_ENABLED', true),\n armor: {\n maxAliases: intEnv('ARMOR_MAX_ALIASES', DEFAULT_ARMOR_CONFIG.maxAliases),\n maxTokens: intEnv('ARMOR_MAX_TOKENS', DEFAULT_ARMOR_CONFIG.maxTokens),\n maxDirectives: intEnv('ARMOR_MAX_DIRECTIVES', DEFAULT_ARMOR_CONFIG.maxDirectives),\n characterLimit: intEnv('ARMOR_CHARACTER_LIMIT', DEFAULT_ARMOR_CONFIG.characterLimit),\n costLimit: intEnv('ARMOR_COST_LIMIT', DEFAULT_ARMOR_CONFIG.costLimit),\n observe: boolEnv('ARMOR_OBSERVE', true),\n },\n queryComplexity: {\n enabled: boolEnv('QUERY_COMPLEXITY_ENABLED', true),\n maxCost: intEnv('QUERY_COMPLEXITY_MAX', 2000),\n costMap: costMapOverride ? mergeCostMap(DEFAULT_COST_MAP, costMapOverride) : DEFAULT_COST_MAP,\n observe: boolEnv('QUERY_COMPLEXITY_OBSERVE', true),\n },\n rateLimit: {\n tiers: resolveTiersFromEnv(),\n keyPrefix: strEnv('VALKEY_KEY_PREFIX', gatewayName),\n observeOnly: boolEnv('RATE_LIMIT_OBSERVE_ONLY', true),\n failClosed: boolEnv('RATE_LIMIT_FAIL_CLOSED', false),\n perWorkspace: {\n // Per-workspace aggregate limiter. observe-only period ended 2026-07-05\n // (2-day bake verified zero normal-usage trips at 6000 req/min budget).\n // Override with RATE_LIMIT_WS_OBSERVE_ONLY=true to revert to measure-only.\n enabled: boolEnv('RATE_LIMIT_WS_ENABLED', true),\n points: intEnv('RATE_LIMIT_WS_POINTS', 6000),\n duration: intEnv('RATE_LIMIT_WS_DURATION', 60),\n burst: intEnv('RATE_LIMIT_WS_BURST', 2000),\n observeOnly: boolEnv('RATE_LIMIT_WS_OBSERVE_ONLY', false),\n },\n },\n operationTimeout: {\n // Default 15s — shorter than the 30s request-limiter queueTimeout, and\n // aligned with typical client-side timeouts so load-shedding fires at\n // the same edge a saturated client would already give up. Mutations\n // that legitimately take longer can override per-deployment via the\n // OPERATION_TIMEOUT_MS env var.\n timeoutMs: intEnv('OPERATION_TIMEOUT_MS', 15000),\n },\n otel: {\n enabled: boolEnv('OTEL_ENABLED', true),\n serviceName: strEnv('OTEL_SERVICE_NAME', gatewayName),\n // Defaults to the collector in this gateway's OWN cluster, derived from\n // the gateway name (`wspace-*` -> otel-collector-wspace, `global-*` ->\n // otel-collector). The previous default,\n // `tempo.tooling.internal.burdenoff.com`, was a retired Azure host and\n // had resolved to nothing since the 2026-08-15 decommission.\n //\n // This is a full signal URL, not a base: OTLPTraceExporter takes `url`\n // verbatim and does not append `/v1/traces` itself.\n endpoint: strEnv('OTEL_EXPORTER_OTLP_ENDPOINT', defaultCollectorTracesEndpoint(gatewayName)),\n environment: strEnv('NODE_ENV', 'development'),\n version: process.env['APP_VERSION'],\n },\n };\n};\n","/**\n * Valkey Client Bootstrap for Gateway Security\n *\n * Wraps the SDK's existing getValkeyClient() (@valkey/valkey-glide) to expose a\n * minimal, stable surface for the rate-limit plugin. Falls back to an\n * in-memory stub so unit tests and local dev without Valkey do not error.\n *\n * @module gateway/security/valkey\n * @category Gateway\n */\n\nimport { logger } from '../../logger/index.js';\nimport type { SecurityValkeyClient } from './types.js';\n\n/**\n * `ioredis` adapter. Used when `VALKEY_CLIENT=ioredis` or as the Bun-compat\n * fallback when `@valkey/valkey-glide` throws at runtime (known issue:\n * `util.Buffer.byteLength` under Bun 1.3.x).\n */\ntype IoRedisInstance = {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, mode?: string, duration?: number): Promise<string | null>;\n incrby(key: string, amount: number): Promise<number>;\n expire(key: string, seconds: number): Promise<number>;\n ttl(key: string): Promise<number>;\n ping(): Promise<string>;\n quit(): Promise<string>;\n on(event: string, listener: (...args: unknown[]) => void): void;\n};\n\nclass IoRedisAdapter implements SecurityValkeyClient {\n constructor(private readonly client: IoRedisInstance) {}\n\n get(key: string): Promise<string | null> {\n return this.client.get(key);\n }\n\n set(key: string, value: string, options?: { EX?: number }): Promise<string | null> {\n if (options?.EX) {\n return this.client.set(key, value, 'EX', options.EX);\n }\n return this.client.set(key, value);\n }\n\n incrBy(key: string, amount: number): Promise<number> {\n return this.client.incrby(key, amount);\n }\n\n async expire(key: string, seconds: number): Promise<boolean> {\n const result = await this.client.expire(key, seconds);\n return result === 1;\n }\n\n ttl(key: string): Promise<number> {\n return this.client.ttl(key);\n }\n\n ping(): Promise<string> {\n return this.client.ping();\n }\n}\n\nconst buildIoRedisClient = async (url: string): Promise<SecurityValkeyClient> => {\n const spec = 'ioredis';\n const mod = (await import(/* @vite-ignore */ spec)) as unknown as {\n default?: new (url: string) => IoRedisInstance;\n Redis?: new (url: string) => IoRedisInstance;\n };\n const Ctor = mod.default ?? mod.Redis;\n if (!Ctor) {\n throw new Error('ioredis module has no Redis constructor');\n }\n const client = new Ctor(url);\n client.on('error', (err) => {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] ioredis error event', { error: e.message });\n });\n return new IoRedisAdapter(client);\n};\n\ntype MemoryEntry = {\n value: string;\n expiresAt: number;\n};\n\n/**\n * Tiny in-memory fallback. Not cross-pod safe; used only when Valkey is\n * absent (e.g., unit tests, local dev without `docker compose up`).\n */\nclass MemoryValkey implements SecurityValkeyClient {\n private store = new Map<string, MemoryEntry>();\n\n private prune(key: string): MemoryEntry | undefined {\n const e = this.store.get(key);\n if (!e) return undefined;\n if (e.expiresAt > 0 && e.expiresAt <= Date.now()) {\n this.store.delete(key);\n return undefined;\n }\n return e;\n }\n\n get(key: string): Promise<string | null> {\n const e = this.prune(key);\n return Promise.resolve(e?.value ?? null);\n }\n\n set(key: string, value: string, options?: { EX?: number }): Promise<string | null> {\n this.store.set(key, {\n value,\n expiresAt: options?.EX ? Date.now() + options.EX * 1000 : 0,\n });\n return Promise.resolve('OK');\n }\n\n incrBy(key: string, amount: number): Promise<number> {\n const e = this.prune(key);\n const next = (e ? parseInt(e.value, 10) || 0 : 0) + amount;\n this.store.set(key, { value: String(next), expiresAt: e?.expiresAt ?? 0 });\n return Promise.resolve(next);\n }\n\n expire(key: string, seconds: number): Promise<boolean> {\n const e = this.store.get(key);\n if (!e) return Promise.resolve(false);\n e.expiresAt = Date.now() + seconds * 1000;\n return Promise.resolve(true);\n }\n\n ttl(key: string): Promise<number> {\n const e = this.prune(key);\n if (!e) return Promise.resolve(-2);\n if (e.expiresAt === 0) return Promise.resolve(-1);\n return Promise.resolve(Math.max(0, Math.ceil((e.expiresAt - Date.now()) / 1000)));\n }\n\n ping(): Promise<string> {\n return Promise.resolve('PONG');\n }\n}\n\nlet singleton: SecurityValkeyClient | null = null;\nlet bootPromise: Promise<SecurityValkeyClient> | null = null;\n\n/**\n * Initialize the Valkey client for the gateway. Reads `VALKEY_URL` (or\n * `REDIS_URL`) + `VALKEY_PASSWORD` from env. On failure: if `VALKEY_REQUIRED`\n * is set to `\"true\"`, throws; otherwise logs a warning and returns the memory\n * fallback so the gateway still boots.\n *\n * Safe to call multiple times — the result is memoized.\n */\nexport const initializeSecurityValkey = async (gatewayName: string): Promise<SecurityValkeyClient> => {\n if (singleton) return singleton;\n if (bootPromise) return bootPromise;\n\n bootPromise = (async (): Promise<SecurityValkeyClient> => {\n const url = process.env['VALKEY_URL'] || process.env['REDIS_URL'];\n const required = process.env['VALKEY_REQUIRED'] === 'true';\n const clientKind = process.env['VALKEY_CLIENT'] ?? 'ioredis';\n\n if (!url) {\n const msg = '[gateway-security] VALKEY_URL not set';\n if (required) throw new Error(`${msg} and VALKEY_REQUIRED=true`);\n logger.warn(`${msg} — using in-memory fallback (not cross-pod safe)`, {\n gatewayName,\n });\n singleton = new MemoryValkey();\n return singleton;\n }\n\n const attempts: Array<{\n kind: string;\n factory: () => Promise<SecurityValkeyClient>;\n }> = [];\n\n if (clientKind === 'ioredis') {\n attempts.push({ kind: 'ioredis', factory: () => buildIoRedisClient(url) });\n attempts.push({\n kind: 'glide (fallback)',\n factory: async () => {\n const { getValkeyClient } = await import('../../cache/index.js');\n return getValkeyClient();\n },\n });\n } else {\n attempts.push({\n kind: 'glide',\n factory: async () => {\n const { getValkeyClient } = await import('../../cache/index.js');\n return getValkeyClient();\n },\n });\n attempts.push({ kind: 'ioredis (fallback)', factory: () => buildIoRedisClient(url) });\n }\n\n let lastError: Error | null = null;\n for (const attempt of attempts) {\n try {\n const client = await attempt.factory();\n const pong = await client.ping();\n if (pong !== 'PONG') {\n throw new Error(`ping returned ${pong}`);\n }\n logger.info('[gateway-security] Valkey connected', {\n gatewayName,\n url,\n client: attempt.kind,\n });\n singleton = client;\n return client;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] Valkey client init failed, will try next', {\n gatewayName,\n client: attempt.kind,\n error: lastError.message,\n });\n }\n }\n\n if (required) {\n logger.error('[gateway-security] Valkey connection failed and required=true', {\n gatewayName,\n error: lastError?.message ?? 'all attempts failed',\n });\n throw lastError ?? new Error('Valkey connection failed');\n }\n logger.warn('[gateway-security] All Valkey clients failed — using in-memory fallback', {\n gatewayName,\n error: lastError?.message ?? 'unknown',\n });\n singleton = new MemoryValkey();\n return singleton;\n })();\n\n return bootPromise;\n};\n\n/**\n * Return the initialized client. Throws if `initializeSecurityValkey` was not\n * called first — keeps the plugin wiring explicit.\n */\nexport const getSecurityValkey = (): SecurityValkeyClient => {\n if (!singleton) {\n throw new Error('[gateway-security] Valkey not initialized — call initializeSecurityValkey() first');\n }\n return singleton;\n};\n\n/**\n * Test-only seam. Replaces the singleton with a stub.\n * Do NOT use in production code.\n */\nexport const __setSecurityValkeyForTest = (client: SecurityValkeyClient | null): void => {\n singleton = client;\n bootPromise = client ? Promise.resolve(client) : null;\n};\n\nexport { MemoryValkey };\n","/**\n * Prometheus Metrics for Gateway Security Plugins\n *\n * Thin wrapper over `prom-client` — optional peer dep. When prom-client is\n * not installed or `PROMETHEUS_METRICS_ENABLED !== 'true'`, every emit is a\n * no-op so the SDK remains consumable without pulling the dependency.\n *\n * Metrics:\n * - `gateway_security_rate_limit_total{gateway,tier,decision}`\n * decision ∈ allowed | rejected | observed_reject\n * - `gateway_security_complexity_rejected_total{gateway,observe}`\n * - `gateway_security_armor_rejected_total{gateway,rule}` (reserved —\n * wiring depends on armor plugin emitting hooks)\n * - `gateway_security_valkey_failover_total{gateway}`\n * - `gateway_security_operation_timeout_total{gateway}`\n *\n * Labels:\n * - `gateway` — gateway name (wspace-public-gateway | global-public-gateway)\n * - `tier` — public | user | app | service | super_admin\n * - `decision` — allowed | rejected | observed_reject\n * - `observe` — 'true' | 'false'\n * - `rule` — armor rule ref (max_aliases, max_tokens, …)\n *\n * All metrics are global singletons across plugin instances. Safe to call\n * `initializeMetrics()` multiple times; subsequent calls are no-ops.\n *\n * @module gateway/security/metrics\n * @category Gateway\n */\n\nimport { logger } from '../../logger/index.js';\n\n// Lightweight type shims for prom-client — keeps this file usable without\n// the peer dep installed.\ntype CounterLike = {\n inc(labels?: Record<string, string>, value?: number): void;\n};\n\ntype CounterCtor = new (opts: { name: string; help: string; labelNames?: string[] }) => CounterLike;\n\ntype PromClientModule = {\n Counter?: CounterCtor;\n register?: { metrics(): Promise<string>; contentType: string };\n};\n\ninterface Metrics {\n rateLimit: CounterLike;\n complexityRejected: CounterLike;\n armorRejected: CounterLike;\n valkeyFailover: CounterLike;\n operationTimeout: CounterLike;\n}\n\nlet metrics: Metrics | null = null;\nlet initializing = false;\nlet promMod: PromClientModule | null = null;\n\nconst noopCounter: CounterLike = {\n inc: () => undefined,\n};\n\nconst noopMetrics: Metrics = {\n rateLimit: noopCounter,\n complexityRejected: noopCounter,\n armorRejected: noopCounter,\n valkeyFailover: noopCounter,\n operationTimeout: noopCounter,\n};\n\n/**\n * Initialize the metrics registry. Safe to call multiple times.\n * Returns a no-op metrics object if prom-client is unavailable.\n */\nexport const initializeMetrics = async (): Promise<Metrics> => {\n if (metrics) return metrics;\n if (initializing) {\n // Another caller is mid-init; return noop to avoid races.\n return noopMetrics;\n }\n if (process.env['PROMETHEUS_METRICS_ENABLED'] !== 'true') {\n logger.info('[gateway-security] Prometheus metrics disabled (PROMETHEUS_METRICS_ENABLED!=true)');\n metrics = noopMetrics;\n return metrics;\n }\n\n initializing = true;\n try {\n const spec = 'prom-client';\n const imported = (await import(/* @vite-ignore */ spec)) as unknown as PromClientModule;\n promMod = imported;\n if (typeof imported.Counter !== 'function') {\n logger.warn('[gateway-security] prom-client has unexpected shape — metrics disabled');\n metrics = noopMetrics;\n return metrics;\n }\n\n const { Counter } = imported;\n metrics = {\n rateLimit: new Counter({\n name: 'gateway_security_rate_limit_total',\n help: 'Rate-limit plugin decisions by tier + gateway',\n labelNames: ['gateway', 'tier', 'decision'],\n }),\n complexityRejected: new Counter({\n name: 'gateway_security_complexity_rejected_total',\n help: 'Query complexity plugin rejections',\n labelNames: ['gateway', 'observe'],\n }),\n armorRejected: new Counter({\n name: 'gateway_security_armor_rejected_total',\n help: 'graphql-armor rule rejections',\n labelNames: ['gateway', 'rule', 'mode'],\n }),\n valkeyFailover: new Counter({\n name: 'gateway_security_valkey_failover_total',\n help: 'Rate-limit plugin fail-open events due to Valkey unreachable',\n labelNames: ['gateway'],\n }),\n operationTimeout: new Counter({\n name: 'gateway_security_operation_timeout_total',\n help: 'Operation timeout plugin aborts',\n labelNames: ['gateway'],\n }),\n };\n logger.info('[gateway-security] Prometheus metrics initialized');\n return metrics;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] prom-client not installed — metrics disabled', {\n error: e.message,\n });\n metrics = noopMetrics;\n return metrics;\n } finally {\n initializing = false;\n }\n};\n\n/**\n * Get the current metrics handle. Returns a noop object if\n * `initializeMetrics()` has not been called or prom-client is unavailable.\n * Always safe to call.\n */\nexport const getMetrics = (): Metrics => metrics ?? noopMetrics;\n\n/**\n * Return the Prometheus registry's default `/metrics` output. Returns\n * `null` if prom-client is not installed.\n */\nexport const scrapeMetrics = async (): Promise<{ body: string; contentType: string } | null> => {\n if (!promMod?.register) return null;\n const body = await promMod.register.metrics();\n return { body, contentType: promMod.register.contentType };\n};\n\n/**\n * Test-only reset. Drops the initialized counters. Do NOT use in production.\n */\nexport const __resetMetricsForTest = (): void => {\n metrics = null;\n initializing = false;\n promMod = null;\n};\n","/**\n * GraphQL Armor Plugin Bundle\n *\n * Wraps the `@escape.tech/graphql-armor-*` validation rules into a single\n * Envelop plugin that runs them inside `onValidate` and sets rejection via\n * `setResult(errors)` — the same pattern that `query-complexity` uses and\n * that Hive Gateway Runtime is confirmed to honor.\n *\n * Why not just use each armor package's own `plugin` factory (which wraps\n * the rule via `addValidationRule`)? Because Hive Gateway Runtime's plugin\n * system does not honor the `addValidationRule` registration path during\n * query validation — rules registered that way are silently dropped. Nor\n * does Hive honor `afterValidate` hooks returned from `onValidate`, which\n * was the first workaround we tried. Only `setResult(errors)` called\n * synchronously inside `onValidate` actually propagates to the client.\n *\n * Rule coverage:\n * - max-aliases (graphql-armor rule)\n * - max-directives (graphql-armor rule)\n * - cost-limit (graphql-armor rule; heuristic pre-pass)\n * - character-limit (implemented inline via `onParse.source.length`\n * because the armor package hooks `onParams` which\n * is not exposed by Envelop — equivalent protection)\n * - block-field-suggestions (still uses the armor plugin — hooks onValidate\n * via `setResult`, which does work)\n * - max-tokens (covered by query-complexity, not re-implemented;\n * token blowup shows up as high cost)\n *\n * In observe mode, rule errors are logged but not attached to the final\n * result — the query proceeds as if nothing happened.\n *\n * @module gateway/security/plugins/armor\n * @category Gateway\n */\n\nimport { GraphQLError, validate as graphqlValidate, type ValidationContext, type ValidationRule } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { getMetrics } from '../metrics.js';\nimport type { ArmorConfig } from '../types.js';\n\ntype RuleFactory = (options: Record<string, unknown>) => ValidationRule;\n\ntype ArmorModule = Record<string, unknown>;\n\nconst tryImport = async (specifier: string): Promise<ArmorModule | null> => {\n try {\n return (await import(specifier)) as ArmorModule;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] armor package not installed — rule skipped', {\n specifier,\n error: e.message,\n });\n return null;\n }\n};\n\nconst pickFactory = (mod: ArmorModule | null, candidates: string[]): RuleFactory | null => {\n if (!mod) return null;\n for (const name of candidates) {\n const fn = mod[name];\n if (typeof fn === 'function') return fn as RuleFactory;\n }\n return null;\n};\n\nconst createMaxAliasesRule = (maxAliases: number): ValidationRule => {\n return (context: ValidationContext) => {\n let aliases = 0;\n\n return {\n Field(node) {\n if (!node.alias) return;\n aliases += 1;\n if (aliases > maxAliases) {\n context.reportError(\n new GraphQLError('Too many field aliases.', {\n nodes: node,\n extensions: { code: 'ARMOR_MAX_ALIASES' },\n })\n );\n }\n },\n };\n };\n};\n\nconst createMaxDirectivesRule = (maxDirectives: number): ValidationRule => {\n return (context: ValidationContext) => {\n let directives = 0;\n\n return {\n Directive(node) {\n directives += 1;\n if (directives > maxDirectives) {\n context.reportError(\n new GraphQLError('Too many directives.', {\n nodes: node,\n extensions: { code: 'ARMOR_MAX_DIRECTIVES' },\n })\n );\n }\n },\n };\n };\n};\n\ninterface LoadedRules {\n maxAliasesRule?: ValidationRule;\n maxDirectivesRule?: ValidationRule;\n costLimitRule?: ValidationRule;\n blockSuggestionsPlugin?: Plugin;\n}\n\n/**\n * When `ARMOR_LEAN=true` (default: false), the gateway loads only the cost-limit\n * rule and skips `max-aliases`, `max-directives`, and `block-field-suggestions`.\n *\n * Rationale: each `@escape.tech/graphql-armor-*` rule runs its own\n * `graphqlValidate(document, [rule])` — a full AST traversal per request. On\n * busy public gateways this shows up as a measurable fraction of total CPU.\n * The cost-limit rule already covers the DoS surface (it rejects expensive\n * aliased-or-deeply-nested queries via the heuristic cost function), and\n * character-limit is handled inline in `onParse`, so the other three rules\n * are refinements rather than load-bearing defences.\n *\n * Opt-in via env so existing services see no behavior change.\n */\nconst isLean = (): boolean => {\n const v = process.env['ARMOR_LEAN'];\n return v === 'true' || v === '1';\n};\n\nconst loadRules = async (cfg: ArmorConfig): Promise<LoadedRules> => {\n const lean = isLean();\n\n const [aliasesMod, directivesMod, costMod, blockSuggestionsMod] = await Promise.all([\n lean ? Promise.resolve(null) : tryImport('@escape.tech/graphql-armor-max-aliases'),\n lean ? Promise.resolve(null) : tryImport('@escape.tech/graphql-armor-max-directives'),\n tryImport('@escape.tech/graphql-armor-cost-limit'),\n lean ? Promise.resolve(null) : tryImport('@escape.tech/graphql-armor-block-field-suggestions'),\n ]);\n\n const loaded: LoadedRules = {};\n\n const maxAliasesFactory = pickFactory(aliasesMod, ['maxAliasesRule']);\n loaded.maxAliasesRule = maxAliasesFactory\n ? maxAliasesFactory({ n: cfg.maxAliases, exposeLimits: cfg.observe })\n : createMaxAliasesRule(cfg.maxAliases);\n\n const maxDirectivesFactory = pickFactory(directivesMod, ['maxDirectivesRule']);\n loaded.maxDirectivesRule = maxDirectivesFactory\n ? maxDirectivesFactory({\n n: cfg.maxDirectives,\n exposeLimits: cfg.observe,\n })\n : createMaxDirectivesRule(cfg.maxDirectives);\n\n const costLimitFactory = pickFactory(costMod, ['costLimitRule']);\n if (costLimitFactory) {\n loaded.costLimitRule = costLimitFactory({\n maxCost: cfg.costLimit,\n objectCost: 2,\n scalarCost: 1,\n depthCostFactor: 1.5,\n ignoreIntrospection: true,\n exposeLimits: cfg.observe,\n });\n }\n\n const blockSuggestionsFactory = pickFactory(blockSuggestionsMod, ['blockFieldSuggestionsPlugin', 'default']);\n if (blockSuggestionsFactory) {\n loaded.blockSuggestionsPlugin = blockSuggestionsFactory({}) as unknown as Plugin;\n }\n\n if (lean) {\n logger.info('[gateway-security] ARMOR_LEAN enabled — running only cost-limit + character-limit', {});\n }\n\n return loaded;\n};\n\n/**\n * Build the Envelop/Yoga plugin list for graphql-armor. Returns the\n * block-field-suggestions plugin (armor's own — this one actually works via\n * `setResult`) plus a custom `onValidate` plugin that runs the rule-based\n * armor checks (max-aliases, max-directives, cost-limit) manually inside\n * `AfterValidate.setResult`.\n *\n * The custom plugin also handles character-limit inline via `onParse`.\n */\nexport const createArmorPlugins = async (cfg: ArmorConfig): Promise<Plugin[]> => {\n const rules = await loadRules(cfg);\n\n const metrics = getMetrics();\n\n // Collect the ValidationRule array once per plugin creation. Envelop's\n // `validateFn` takes an array of rules, but we're bypassing that path and\n // running the rules ourselves inside the afterValidate hook. Each rule is\n // a factory returning a visitor, so this reuse is safe.\n const enabledRules: Array<{ name: string; rule: ValidationRule }> = [];\n if (rules.maxAliasesRule) {\n enabledRules.push({ name: 'max-aliases', rule: rules.maxAliasesRule });\n }\n if (rules.maxDirectivesRule) {\n enabledRules.push({ name: 'max-directives', rule: rules.maxDirectivesRule });\n }\n if (rules.costLimitRule) {\n enabledRules.push({ name: 'cost-limit', rule: rules.costLimitRule });\n }\n\n const armorValidationPlugin: Plugin = {\n onParse({ params }) {\n // Character limit — rejects oversized raw queries before parse even\n // starts. Doing it here is equivalent to graphql-armor-character-limit\n // hooking `onParams`, which is not exposed by Envelop.\n const source = typeof params.source === 'string' ? params.source : params.source?.body;\n if (typeof source === 'string' && source.length > cfg.characterLimit) {\n if (cfg.observe) {\n logger.warn('[gateway-security] armor character-limit exceeded (observe)', {\n length: source.length,\n limit: cfg.characterLimit,\n });\n metrics.armorRejected.inc({ rule: 'character-limit', mode: 'observe' }, 1);\n return;\n }\n metrics.armorRejected.inc({ rule: 'character-limit', mode: 'enforce' }, 1);\n throw new GraphQLError('Syntax Error: Query exceeds maximum character limit.', {\n extensions: {\n code: 'CHARACTER_LIMIT_EXCEEDED',\n http: { status: 400 },\n },\n });\n }\n },\n onValidate({ params, setResult }) {\n if (enabledRules.length === 0) return;\n // Run armor rules manually inside `onValidate`. We initially tried\n // returning an `afterValidate` hook here, but Hive Gateway Runtime\n // silently drops those callbacks — the same class of bug that causes\n // `addValidationRule` not to fire. Doing the work in the synchronous\n // body of `onValidate` + calling `setResult` directly is the pattern\n // that query-complexity uses and it is confirmed to work end-to-end\n // against Hive Gateway.\n //\n // IMPORTANT: graphql-armor rules throw `GraphQLError` synchronously\n // when a limit is exceeded, instead of using the conventional\n // `context.reportError()` path. This propagates as an exception out\n // of `graphqlValidate`, which is why we wrap each rule in an\n // isolated try/catch — otherwise the first throwing rule would hide\n // any subsequent rule failures.\n const armorErrors: GraphQLError[] = [];\n for (const { name, rule } of enabledRules) {\n try {\n const errs = graphqlValidate(params.schema, params.documentAST, [rule]);\n armorErrors.push(...errs);\n } catch (err) {\n // `err instanceof GraphQLError` is NOT reliable here because\n // `@escape.tech/graphql-armor-*` bundles its own copy of\n // `graphql`, so the thrown error's prototype chain does not\n // match the `GraphQLError` class we imported at the top of this\n // file even when both resolve to the same package semver range.\n // We therefore detect armor rule violations by looking at the\n // error shape (either GraphQLError-like or Error-like with a\n // message). Any thrown value from a rule is treated as a\n // violation — rules don't throw for any other reason.\n const message = err instanceof Error ? err.message : String(err);\n const wrapped = new GraphQLError(message, {\n originalError: err instanceof Error ? err : undefined,\n extensions: {\n code: 'ARMOR_VIOLATION',\n rule: name,\n },\n });\n armorErrors.push(wrapped);\n }\n }\n\n if (armorErrors.length === 0) return;\n\n for (const err of armorErrors) {\n logger.warn('[gateway-security] armor rule triggered', {\n message: err.message,\n observe: cfg.observe,\n });\n }\n\n metrics.armorRejected.inc(\n {\n rule: 'armor',\n mode: cfg.observe ? 'observe' : 'enforce',\n },\n armorErrors.length\n );\n\n if (cfg.observe) return;\n\n // Calling `setResult` inside `onValidate` replaces the validation\n // result and skips envelop's own validate invocation. That is exactly\n // what we want — armor violations are fatal, no point running the\n // default graphql-js validation afterwards.\n setResult(armorErrors);\n },\n };\n\n const plugins: Plugin[] = [armorValidationPlugin];\n if (rules.blockSuggestionsPlugin) {\n plugins.push(rules.blockSuggestionsPlugin);\n }\n return plugins;\n};\n","/**\n * Operation Timeout Plugin\n *\n * Races each operation against a configurable timer (default 15s, aligned\n * with typical client-side timeouts and shorter than the 30s request-limiter\n * cap). When the timer fires, the execution errors out with a proper\n * GraphQL error (`OPERATION_TIMEOUT`) rather than the client seeing an\n * abrupt TCP drop.\n *\n * This is implemented via `onExecute` with a promise race — the subgraph\n * fetch already honors AbortController from Yoga, so upstream work is\n * cancelled naturally.\n *\n * @module gateway/security/plugins/operation-timeout\n * @category Gateway\n */\n\nimport { GraphQLError } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\n\nimport type { OperationTimeoutConfig } from '../types.js';\n\nexport interface OperationTimeoutPluginDeps {\n config: OperationTimeoutConfig;\n}\n\ninterface TimerHandle {\n timer: ReturnType<typeof setTimeout>;\n promise: Promise<never>;\n}\n\nconst createTimeoutHandle = (timeoutMs: number, error: GraphQLError): TimerHandle => {\n let timerRef: ReturnType<typeof setTimeout> | undefined;\n const promise = new Promise<never>((_, reject) => {\n timerRef = setTimeout(() => reject(error), timeoutMs);\n });\n return { timer: timerRef as ReturnType<typeof setTimeout>, promise };\n};\n\nexport const createOperationTimeoutPlugin = (deps: OperationTimeoutPluginDeps): Plugin => {\n const timeoutError = new GraphQLError('Operation timeout', {\n extensions: { code: 'OPERATION_TIMEOUT', timeoutMs: deps.config.timeoutMs },\n });\n\n return {\n onExecute: ({ executeFn, setExecuteFn }) => {\n setExecuteFn(async (args) => {\n const handle = createTimeoutHandle(deps.config.timeoutMs, timeoutError);\n try {\n return await Promise.race([executeFn(args), handle.promise]);\n } finally {\n clearTimeout(handle.timer);\n }\n });\n },\n };\n};\n","/**\n * OpenTelemetry Plugin\n *\n * Initializes an OTLP HTTP exporter pointed at Tempo (or any OTLP/HTTP\n * endpoint) and installs `@envelop/opentelemetry` spans around `parse`,\n * `validate`, and `execute`. Imports are dynamic so the SDK stays usable\n * when OTel is disabled or the peer packages are absent.\n *\n * Enrichment: spans carry `gateway.name`, `deployment.environment`, and\n * `service.version` resource attrs. Per-request context (actor, workspace)\n * is propagated via headers because the SDK does not yet wire\n * `propagators` — see the gateway handler edits for `traceparent` forwarding.\n *\n * @module gateway/security/plugins/otel\n * @category Gateway\n */\n\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport type { OtelConfig } from '../types.js';\n\nlet shutdownHook: (() => Promise<void>) | null = null;\n\n// Structural types for the optional OTel peer deps. Constructors accept\n// `unknown` opts because we only need the start/shutdown surface here.\ntype ResourceCtor = new (attrs: Record<string, string>) => unknown;\ntype ResourceFactory = (attrs: Record<string, string>) => unknown;\ntype OtlpExporterCtor = new (opts: { url: string }) => unknown;\ntype NodeSdkInstance = { start(): void; shutdown(): Promise<void> };\ntype NodeSdkCtor = new (opts: { resource: unknown; traceExporter: unknown }) => NodeSdkInstance;\n\ntype ResourceModule = {\n // v1 API\n Resource?: ResourceCtor;\n // v2 API\n resourceFromAttributes?: ResourceFactory;\n};\n\ntype SemanticAttrs = {\n // v1 API\n SemanticResourceAttributes?: {\n SERVICE_NAME: string;\n DEPLOYMENT_ENVIRONMENT: string;\n SERVICE_VERSION: string;\n };\n // v2 API — string constants directly\n ATTR_SERVICE_NAME?: string;\n ATTR_SERVICE_VERSION?: string;\n ATTR_DEPLOYMENT_ENVIRONMENT?: string;\n ATTR_DEPLOYMENT_ENVIRONMENT_NAME?: string;\n};\n\n/**\n * Build an OTel Resource across the v1 → v2 API migration.\n * - v1 (`@opentelemetry/resources` 1.x): `new Resource(attrs)`\n * - v2 (`@opentelemetry/resources` 2.x): `resourceFromAttributes(attrs)`\n */\nconst buildResource = (resMod: ResourceModule, attrs: Record<string, string>): unknown => {\n if (typeof resMod.resourceFromAttributes === 'function') {\n return resMod.resourceFromAttributes(attrs);\n }\n if (typeof resMod.Resource === 'function') {\n return new resMod.Resource(attrs);\n }\n throw new Error('@opentelemetry/resources module exposes neither Resource nor resourceFromAttributes');\n};\n\n/**\n * Resolve semantic attribute keys across the v1 → v2 API migration.\n * - v1: `semcon.SemanticResourceAttributes.SERVICE_NAME` etc.\n * - v2: top-level `ATTR_SERVICE_NAME` string constants. Deployment\n * environment was renamed to `ATTR_DEPLOYMENT_ENVIRONMENT_NAME`.\n */\nconst resolveSemanticKeys = (\n semcon: SemanticAttrs\n): { serviceName: string; deploymentEnv: string; serviceVersion: string } => {\n if (semcon.SemanticResourceAttributes) {\n return {\n serviceName: semcon.SemanticResourceAttributes.SERVICE_NAME,\n deploymentEnv: semcon.SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT,\n serviceVersion: semcon.SemanticResourceAttributes.SERVICE_VERSION,\n };\n }\n return {\n serviceName: semcon.ATTR_SERVICE_NAME ?? 'service.name',\n deploymentEnv:\n semcon.ATTR_DEPLOYMENT_ENVIRONMENT_NAME ?? semcon.ATTR_DEPLOYMENT_ENVIRONMENT ?? 'deployment.environment',\n serviceVersion: semcon.ATTR_SERVICE_VERSION ?? 'service.version',\n };\n};\n\nconst loadOtelPeerDeps = async (): Promise<{\n NodeSDK: NodeSdkCtor;\n OTLPTraceExporter: OtlpExporterCtor;\n resMod: ResourceModule;\n semcon: SemanticAttrs;\n}> => {\n // Optional peer deps — indirect specifiers so TS does not try to resolve.\n const sdkSpec = '@opentelemetry/sdk-node';\n const otlpSpec = '@opentelemetry/exporter-trace-otlp-http';\n const resSpec = '@opentelemetry/resources';\n const semSpec = '@opentelemetry/semantic-conventions';\n const modules = (await Promise.all([\n import(/* @vite-ignore */ sdkSpec),\n import(/* @vite-ignore */ otlpSpec),\n import(/* @vite-ignore */ resSpec),\n import(/* @vite-ignore */ semSpec),\n ])) as [{ NodeSDK: NodeSdkCtor }, { OTLPTraceExporter: OtlpExporterCtor }, ResourceModule, SemanticAttrs];\n const [sdkMod, otlpMod, resMod, semcon] = modules;\n return {\n NodeSDK: sdkMod.NodeSDK,\n OTLPTraceExporter: otlpMod.OTLPTraceExporter,\n resMod,\n semcon,\n };\n};\n\nexport const initializeOtel = async (cfg: OtelConfig): Promise<void> => {\n if (!cfg.enabled) {\n logger.info('[gateway-security] OTel disabled by config');\n return;\n }\n if (shutdownHook) {\n return; // already initialized\n }\n\n try {\n const { NodeSDK, OTLPTraceExporter, resMod, semcon } = await loadOtelPeerDeps();\n const keys = resolveSemanticKeys(semcon);\n\n const resourceAttributes: Record<string, string> = {\n [keys.serviceName]: cfg.serviceName,\n [keys.deploymentEnv]: cfg.environment,\n };\n if (cfg.version) {\n resourceAttributes[keys.serviceVersion] = cfg.version;\n }\n\n const sdk = new NodeSDK({\n resource: buildResource(resMod, resourceAttributes),\n traceExporter: new OTLPTraceExporter({ url: cfg.endpoint }),\n });\n\n sdk.start();\n shutdownHook = (): Promise<void> => sdk.shutdown();\n logger.info('[gateway-security] OTel initialized', {\n serviceName: cfg.serviceName,\n endpoint: cfg.endpoint,\n });\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] OTel init failed — continuing without tracing', {\n error: e.message,\n });\n }\n};\n\nexport const shutdownOtel = async (): Promise<void> => {\n if (shutdownHook) {\n try {\n await shutdownHook();\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] OTel shutdown error', { error: e.message });\n }\n shutdownHook = null;\n }\n};\n\n/**\n * Returns an Envelop plugin that adds spans around parse/validate/execute.\n * Returns an empty plugin when @envelop/opentelemetry is absent.\n */\nexport const createOtelPlugin = async (cfg: OtelConfig): Promise<Plugin> => {\n if (!cfg.enabled) return {};\n try {\n const spec = '@envelop/opentelemetry';\n const mod = (await import(/* @vite-ignore */ spec)) as unknown as {\n useOpenTelemetry?: (opts: {\n spans?: { execute?: boolean; parse?: boolean; validate?: boolean; subscribe?: boolean };\n resolvers?: boolean;\n }) => Plugin;\n };\n if (typeof mod.useOpenTelemetry !== 'function') {\n logger.warn('[gateway-security] @envelop/opentelemetry has unexpected shape — plugin skipped');\n return {};\n }\n return mod.useOpenTelemetry({\n spans: { execute: true, parse: true, validate: true, subscribe: true },\n resolvers: false,\n });\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] @envelop/opentelemetry not installed — plugin skipped', {\n error: e.message,\n });\n return {};\n }\n};\n","/**\n * Query Complexity Plugin\n *\n * Scores each incoming query against a per-field cost map. Scoring happens in\n * the validate phase so rejection is cheap and subgraph fanout is prevented.\n *\n * Observe mode logs the computed cost without rejecting — used during the\n * 48h bake of the hardening pass.\n *\n * @module gateway/security/plugins/query-complexity\n * @category Gateway\n */\n\nimport { GraphQLError, Kind } from 'graphql';\nimport type {\n ArgumentNode,\n FieldNode,\n FragmentDefinitionNode,\n GraphQLSchema,\n OperationDefinitionNode,\n SelectionNode,\n SelectionSetNode,\n ValueNode,\n} from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { getMetrics } from '../metrics.js';\nimport type { CostMap, QueryComplexityConfig } from '../types.js';\n\nconst PAGINATION_ARGUMENTS = new Set(['first', 'limit', 'pageSize']);\nconst MAX_LIST_MULTIPLIER = 100;\nconst MAX_FAILURE_LOG_VARIANTS = 5;\nconst complexityFailureMessages = new Set<string>();\n\ninterface GraphQLNamedTypeLike {\n name?: string;\n getFields?: () => Record<string, GraphQLFieldLike | undefined>;\n}\n\ninterface GraphQLFieldLike {\n name?: string;\n type?: unknown;\n}\n\ninterface GraphQLSchemaLike {\n getQueryType?: () => GraphQLNamedTypeLike | null;\n getMutationType?: () => GraphQLNamedTypeLike | null;\n getSubscriptionType?: () => GraphQLNamedTypeLike | null;\n getType?: (name: string) => GraphQLNamedTypeLike | undefined | null;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null;\n\nconst unwrapNamedType = (type: unknown): GraphQLNamedTypeLike | null => {\n let current = type;\n while (isRecord(current) && current['ofType'] !== undefined) {\n current = current['ofType'];\n }\n return isRecord(current) ? current : null;\n};\n\nconst getSchemaLike = (schema: GraphQLSchema): GraphQLSchemaLike => schema as unknown as GraphQLSchemaLike;\n\nconst getOperationRootType = (\n schema: GraphQLSchema,\n operation: OperationDefinitionNode\n): GraphQLNamedTypeLike | null => {\n const schemaLike = getSchemaLike(schema);\n if (operation.operation === 'mutation') return schemaLike.getMutationType?.() ?? null;\n if (operation.operation === 'subscription') return schemaLike.getSubscriptionType?.() ?? null;\n return schemaLike.getQueryType?.() ?? null;\n};\n\nconst getTypeByName = (schema: GraphQLSchema, name: string): GraphQLNamedTypeLike | null => {\n return getSchemaLike(schema).getType?.(name) ?? null;\n};\n\nconst getField = (parentType: GraphQLNamedTypeLike, fieldName: string): GraphQLFieldLike | undefined => {\n return parentType.getFields?.()[fieldName];\n};\n\nconst getCostMapValue = (costMap: CostMap, parentType: GraphQLNamedTypeLike, fieldName: string): number => {\n if (!parentType.name) return 1;\n return costMap[`${parentType.name}.${fieldName}`] ?? 1;\n};\n\nconst numericValueFromAst = (value: ValueNode): number | undefined => {\n if (value.kind === Kind.INT || value.kind === Kind.FLOAT) {\n const parsed = Number(value.value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n if (value.kind === Kind.STRING) {\n const parsed = Number(value.value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n};\n\nconst listMultiplierFromArgs = (args: readonly ArgumentNode[] | undefined): number => {\n if (!args) return 1;\n for (const arg of args) {\n if (!PAGINATION_ARGUMENTS.has(arg.name.value)) continue;\n const raw = numericValueFromAst(arg.value);\n if (typeof raw !== 'number') return 1;\n return Math.min(Math.max(1, Math.trunc(raw)), MAX_LIST_MULTIPLIER);\n }\n return 1;\n};\n\nconst calculateFieldComplexity = (\n schema: GraphQLSchema,\n fieldNode: FieldNode,\n parentType: GraphQLNamedTypeLike,\n fragments: ReadonlyMap<string, FragmentDefinitionNode>,\n costMap: CostMap,\n activeFragments: Set<string>\n): number => {\n const fieldName = fieldNode.name.value;\n const field = getField(parentType, fieldName);\n const baseCost = getCostMapValue(costMap, parentType, fieldName);\n const namedFieldType = unwrapNamedType(field?.type);\n const childCost =\n fieldNode.selectionSet && namedFieldType\n ? calculateSelectionSetComplexity(\n schema,\n fieldNode.selectionSet,\n namedFieldType,\n fragments,\n costMap,\n activeFragments\n )\n : 0;\n return (baseCost + childCost) * listMultiplierFromArgs(fieldNode.arguments);\n};\n\nconst calculateSelectionSetComplexity = (\n schema: GraphQLSchema,\n selectionSet: SelectionSetNode,\n parentType: GraphQLNamedTypeLike,\n fragments: ReadonlyMap<string, FragmentDefinitionNode>,\n costMap: CostMap,\n activeFragments: Set<string>\n): number => {\n let total = 0;\n\n for (const selection of selectionSet.selections) {\n total += calculateSelectionComplexity(schema, selection, parentType, fragments, costMap, activeFragments);\n }\n\n return total;\n};\n\nconst calculateSelectionComplexity = (\n schema: GraphQLSchema,\n selection: SelectionNode,\n parentType: GraphQLNamedTypeLike,\n fragments: ReadonlyMap<string, FragmentDefinitionNode>,\n costMap: CostMap,\n activeFragments: Set<string>\n): number => {\n if (selection.kind === Kind.FIELD) {\n return calculateFieldComplexity(schema, selection, parentType, fragments, costMap, activeFragments);\n }\n\n if (selection.kind === Kind.INLINE_FRAGMENT) {\n const fragmentParent = selection.typeCondition\n ? (getTypeByName(schema, selection.typeCondition.name.value) ?? parentType)\n : parentType;\n return calculateSelectionSetComplexity(\n schema,\n selection.selectionSet,\n fragmentParent,\n fragments,\n costMap,\n activeFragments\n );\n }\n\n const fragmentName = selection.name.value;\n if (activeFragments.has(fragmentName)) return 0;\n const fragment = fragments.get(fragmentName);\n if (!fragment) return 0;\n\n activeFragments.add(fragmentName);\n const fragmentParent = getTypeByName(schema, fragment.typeCondition.name.value) ?? parentType;\n const complexity = calculateSelectionSetComplexity(\n schema,\n fragment.selectionSet,\n fragmentParent,\n fragments,\n costMap,\n activeFragments\n );\n activeFragments.delete(fragmentName);\n return complexity;\n};\n\nconst calculateDocumentComplexity = (\n schema: GraphQLSchema,\n documentAST: { definitions: readonly unknown[] },\n costMap: CostMap\n): number => {\n const fragments = new Map<string, FragmentDefinitionNode>();\n const operations: OperationDefinitionNode[] = [];\n\n for (const definition of documentAST.definitions) {\n if (!isRecord(definition) || typeof definition['kind'] !== 'string') continue;\n if (definition['kind'] === Kind.FRAGMENT_DEFINITION) {\n const fragment = definition as unknown as FragmentDefinitionNode;\n fragments.set(fragment.name.value, fragment);\n } else if (definition['kind'] === Kind.OPERATION_DEFINITION) {\n operations.push(definition as unknown as OperationDefinitionNode);\n }\n }\n\n let maxComplexity = 0;\n for (const operation of operations) {\n const rootType = getOperationRootType(schema, operation);\n if (!rootType) continue;\n const complexity = calculateSelectionSetComplexity(\n schema,\n operation.selectionSet,\n rootType,\n fragments,\n costMap,\n new Set<string>()\n );\n maxComplexity = Math.max(maxComplexity, complexity);\n }\n\n return maxComplexity;\n};\n\nconst logComplexityFailure = (error: Error): void => {\n const seen = complexityFailureMessages.has(error.message);\n if (!seen && complexityFailureMessages.size < MAX_FAILURE_LOG_VARIANTS) {\n complexityFailureMessages.add(error.message);\n logger.warn('[gateway-security] complexity scoring failed — fail-open', {\n error: error.message,\n suppressedRepeats: true,\n });\n return;\n }\n\n logger.debug('[gateway-security] repeated complexity scoring failure suppressed', {\n error: error.message,\n });\n};\n\nexport interface QueryComplexityPluginDeps {\n config: QueryComplexityConfig;\n}\n\nexport const createQueryComplexityPlugin = (deps: QueryComplexityPluginDeps): Plugin => {\n return {\n onValidate: ({ params, setResult }) => {\n try {\n const complexity = calculateDocumentComplexity(params.schema, params.documentAST, deps.config.costMap);\n\n if (complexity > deps.config.maxCost) {\n getMetrics().complexityRejected.inc({\n gateway: 'unknown',\n observe: deps.config.observe ? 'true' : 'false',\n });\n if (deps.config.observe) {\n logger.info('[gateway-security] complexity would_reject (observe)', {\n complexity,\n maxCost: deps.config.maxCost,\n });\n return;\n }\n setResult([\n new GraphQLError(`Query too expensive (cost ${complexity} > limit ${deps.config.maxCost})`, {\n extensions: {\n code: 'COMPLEXITY_TOO_HIGH',\n cost: complexity,\n maxCost: deps.config.maxCost,\n },\n }),\n ]);\n }\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logComplexityFailure(e);\n }\n },\n };\n};\n","/**\n * Rate-Limit Plugin\n *\n * Per-actor token-bucket rate limiter backed by Valkey. Tier classification\n * from ActorContext. Increments a counter with a window-scoped TTL and\n * rejects when the bucket is exhausted. Emits rate-limit response headers\n * on every request (X-RateLimit-Limit / Remaining / Reset).\n *\n * Failure policy: **fail open** by default (availability > strictness during\n * Valkey outages). Flip with `failClosed: true`.\n *\n * Observe mode: when `observeOnly: true`, counts and logs but never rejects.\n * Used during the 48h bake of this hardening pass.\n *\n * @module gateway/security/plugins/rate-limit\n * @category Gateway\n */\n\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { resolveActor } from '../actor.js';\nimport { getMetrics } from '../metrics.js';\nimport type { ActorContext, RateLimitConfig, RateLimitResult, SecurityValkeyClient } from '../types.js';\n\nexport interface RateLimitPluginDeps {\n valkey: SecurityValkeyClient;\n config: RateLimitConfig;\n}\n\nconst keyFor = (prefix: string, tier: string, identity: string): string => `rl:${prefix}:${tier}:${identity}`;\n\nconst wsKeyFor = (prefix: string, workspaceId: string): string => `rl:${prefix}:ws:${workspaceId}`;\n\nconst stamp = (): number => Date.now();\n\n/**\n * Atomic-ish INCR + EXPIRE. Valkey does not guarantee atomicity between the\n * two without a Lua script; the race window here loses at most 1 event per\n * window-start collision, which is acceptable for a limiter and avoids the\n * Lua script registration dance.\n */\nexport const checkRateLimit = async (deps: RateLimitPluginDeps, actor: ActorContext): Promise<RateLimitResult> => {\n const tier = deps.config.tiers[actor.tier];\n const metrics = getMetrics();\n const gateway = deps.config.keyPrefix;\n // Super admin passes through.\n if (tier.points === Number.MAX_SAFE_INTEGER) {\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'allowed' });\n return { allowed: true, remaining: Number.MAX_SAFE_INTEGER, resetAtMs: 0, limit: tier.points };\n }\n\n const key = keyFor(deps.config.keyPrefix, actor.tier, actor.identity);\n const limit = tier.points + tier.burst;\n\n try {\n const count = await deps.valkey.incrBy(key, 1);\n if (count === 1) {\n await deps.valkey.expire(key, tier.duration);\n }\n const ttl = await deps.valkey.ttl(key);\n const resetAtMs = stamp() + Math.max(0, ttl) * 1000;\n\n if (count > limit) {\n metrics.rateLimit.inc({\n gateway,\n tier: actor.tier,\n decision: deps.config.observeOnly ? 'observed_reject' : 'rejected',\n });\n return { allowed: false, remaining: 0, resetAtMs, limit };\n }\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'allowed' });\n return { allowed: true, remaining: Math.max(0, limit - count), resetAtMs, limit };\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] rate-limit valkey error — fail-open', {\n key,\n error: e.message,\n });\n metrics.valkeyFailover.inc({ gateway });\n if (deps.config.failClosed) {\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'rejected' });\n return { allowed: false, remaining: 0, resetAtMs: stamp() + tier.duration * 1000, limit };\n }\n metrics.rateLimit.inc({ gateway, tier: actor.tier, decision: 'allowed' });\n return { allowed: true, remaining: -1, resetAtMs: 0, limit };\n }\n};\n\n/**\n * Per-workspace AGGREGATE rate limit. The per-actor limiter (checkRateLimit)\n * caps each user; this caps the whole workspace so that N users in one workspace\n * cannot collectively starve other workspaces on the shared backend. Runs only\n * when a workspaceId is present. Emits the decision under `tier: 'workspace'`\n * (workspaceId is logged, NOT a metric label, to avoid metric cardinality\n * blow-up). Always fails OPEN on a Valkey error — a fairness signal must never be\n * an availability dependency.\n */\nexport const checkWorkspaceRateLimit = async (\n deps: RateLimitPluginDeps,\n workspaceId: string\n): Promise<RateLimitResult> => {\n const cfg = deps.config.perWorkspace;\n const metrics = getMetrics();\n const gateway = deps.config.keyPrefix;\n const key = wsKeyFor(deps.config.keyPrefix, workspaceId);\n const limit = cfg.points + cfg.burst;\n\n try {\n const count = await deps.valkey.incrBy(key, 1);\n if (count === 1) {\n await deps.valkey.expire(key, cfg.duration);\n }\n const ttl = await deps.valkey.ttl(key);\n const resetAtMs = stamp() + Math.max(0, ttl) * 1000;\n\n if (count > limit) {\n metrics.rateLimit.inc({\n gateway,\n tier: 'workspace',\n decision: cfg.observeOnly ? 'observed_reject' : 'rejected',\n });\n // workspaceId in the LOG (not a metric label) → noisy-neighbor leaderboard\n logger.warn('[gateway-security] workspace rate-limit exceeded', {\n workspaceId,\n count,\n limit,\n observe: cfg.observeOnly,\n });\n return { allowed: false, remaining: 0, resetAtMs, limit };\n }\n metrics.rateLimit.inc({ gateway, tier: 'workspace', decision: 'allowed' });\n return { allowed: true, remaining: Math.max(0, limit - count), resetAtMs, limit };\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n logger.warn('[gateway-security] workspace rate-limit valkey error — fail-open', {\n key,\n error: e.message,\n });\n metrics.valkeyFailover.inc({ gateway });\n return { allowed: true, remaining: -1, resetAtMs: 0, limit };\n }\n};\n\n/**\n * Yoga/Envelop plugin factory.\n */\nexport const createRateLimitPlugin = (deps: RateLimitPluginDeps): Plugin => {\n return {\n onRequest: async ({ request, fetchAPI, endResponse }): Promise<void> => {\n const actor = resolveActor((name) => request.headers.get(name));\n const result = await checkRateLimit(deps, actor);\n\n // Headers are set via onResponse (below). Stash the result on the request\n // so onResponse can read it without re-running the Valkey call.\n (request as unknown as { __rateLimitResult: RateLimitResult; __rateLimitActor: ActorContext }).__rateLimitResult =\n result;\n (request as unknown as { __rateLimitResult: RateLimitResult; __rateLimitActor: ActorContext }).__rateLimitActor =\n actor;\n\n // Per-workspace aggregate limiter (fairness). Independent of the per-actor\n // bucket: measures the whole workspace's request rate so one workspace's\n // many users can't collectively starve others. Observe-only by default →\n // it records + logs but does not reject; enforcement is opt-in.\n const workspaceId = actor.headers.workspaceId;\n if (deps.config.perWorkspace.enabled && workspaceId) {\n const wsResult = await checkWorkspaceRateLimit(deps, workspaceId);\n if (!wsResult.allowed && !deps.config.perWorkspace.observeOnly) {\n const retryAfterS = Math.max(1, Math.ceil((wsResult.resetAtMs - stamp()) / 1000));\n const body = JSON.stringify({\n errors: [\n {\n message: 'Workspace rate limit exceeded',\n extensions: {\n code: 'RATE_LIMITED',\n scope: 'workspace',\n resetAt: new Date(wsResult.resetAtMs).toISOString(),\n },\n },\n ],\n });\n endResponse(\n new fetchAPI.Response(body, {\n status: 429,\n headers: {\n 'content-type': 'application/json',\n 'retry-after': String(retryAfterS),\n 'x-ratelimit-scope': 'workspace',\n 'x-ratelimit-limit': String(wsResult.limit),\n 'x-ratelimit-remaining': '0',\n 'x-ratelimit-reset': String(Math.floor(wsResult.resetAtMs / 1000)),\n },\n })\n );\n return;\n }\n }\n\n if (!result.allowed) {\n if (deps.config.observeOnly) {\n logger.info('[gateway-security] rate-limit would_reject (observe)', {\n tier: actor.tier,\n identity: actor.identity,\n limit: result.limit,\n });\n return;\n }\n const retryAfterS = Math.max(1, Math.ceil((result.resetAtMs - stamp()) / 1000));\n const body = JSON.stringify({\n errors: [\n {\n message: 'Rate limit exceeded',\n extensions: {\n code: 'RATE_LIMITED',\n resetAt: new Date(result.resetAtMs).toISOString(),\n },\n },\n ],\n });\n const response = new fetchAPI.Response(body, {\n status: 429,\n headers: {\n 'content-type': 'application/json',\n 'retry-after': String(retryAfterS),\n 'x-ratelimit-limit': String(result.limit),\n 'x-ratelimit-remaining': '0',\n 'x-ratelimit-reset': String(Math.floor(result.resetAtMs / 1000)),\n },\n });\n endResponse(response);\n }\n },\n onResponse: ({ request, response }): void => {\n const stash = (request as unknown as { __rateLimitResult?: RateLimitResult }).__rateLimitResult;\n if (!stash) return;\n response.headers.set('x-ratelimit-limit', String(stash.limit));\n response.headers.set('x-ratelimit-remaining', String(Math.max(0, stash.remaining)));\n if (stash.resetAtMs > 0) {\n response.headers.set('x-ratelimit-reset', String(Math.floor(stash.resetAtMs / 1000)));\n }\n },\n };\n};\n","/**\n * Gateway Security Plugin Orchestrator\n *\n * Builds the ordered Yoga/Envelop plugin array consumed by each public\n * gateway via `createGatewayRuntime({ plugins: [...] })`.\n *\n * Order (cheapest rejection first, span wrapping everything):\n * otel spans → armor (6 sub-plugins) → query-complexity → rate-limit → timeout\n *\n * @module gateway/security/plugins\n * @category Gateway\n */\n\nimport type { Plugin } from 'graphql-yoga';\n\nimport { logger } from '../../../logger/index.js';\nimport { initializeMetrics } from '../metrics.js';\nimport type { GatewaySecurityOptions } from '../types.js';\nimport { initializeSecurityValkey } from '../valkey.js';\nimport { createArmorPlugins } from './armor.js';\nimport { createOperationTimeoutPlugin } from './operation-timeout.js';\nimport { createOtelPlugin } from './otel.js';\nimport { createQueryComplexityPlugin } from './query-complexity.js';\nimport { createRateLimitPlugin } from './rate-limit.js';\n\n/**\n * Bootstraps Valkey + OTel side effects and returns the ordered plugin list.\n * Safe to call once at gateway boot; subsequent calls reuse the initialized\n * singletons.\n *\n * If `options.enabled === false`, returns an empty array — the master kill\n * switch for instant rollback via env flag.\n */\nexport const buildSecurityPlugins = async (options: GatewaySecurityOptions): Promise<Plugin[]> => {\n if (!options.enabled) {\n logger.warn('[gateway-security] SECURITY_PLUGINS_ENABLED=false — plugins disabled', {\n gatewayName: options.gatewayName,\n });\n return [];\n }\n\n // Side-effect init (both are idempotent). OTel exporter bootstrap belongs to\n // `bootstrapTelemetry()`; this stack only wires Envelop span hooks.\n await initializeMetrics();\n const valkey = await initializeSecurityValkey(options.gatewayName);\n\n const plugins: Plugin[] = [];\n\n const otelPlugin = await createOtelPlugin(options.otel);\n plugins.push(otelPlugin);\n\n const armorPlugins = await createArmorPlugins(options.armor);\n plugins.push(...armorPlugins);\n\n if (options.queryComplexity.enabled) {\n plugins.push(createQueryComplexityPlugin({ config: options.queryComplexity }));\n }\n plugins.push(createRateLimitPlugin({ valkey, config: options.rateLimit }));\n plugins.push(createOperationTimeoutPlugin({ config: options.operationTimeout }));\n\n logger.info('[gateway-security] plugins wired', {\n gatewayName: options.gatewayName,\n count: plugins.length,\n observe: {\n armor: options.armor.observe,\n complexity: options.queryComplexity.observe,\n rateLimit: options.rateLimit.observeOnly,\n },\n enabled: {\n complexity: options.queryComplexity.enabled,\n },\n });\n\n return plugins;\n};\n\nexport { createArmorPlugins } from './armor.js';\nexport { createOperationTimeoutPlugin } from './operation-timeout.js';\nexport { createOtelPlugin, initializeOtel, shutdownOtel } from './otel.js';\nexport { createQueryComplexityPlugin } from './query-complexity.js';\nexport { checkRateLimit, createRateLimitPlugin } from './rate-limit.js';\n"]}
|