version: 1 security: requireProtectionOnPublicListen: true gateway: enabled: true listen: 0.0.0.0:8080 access: allowCIDRs: [172.16.0.0/12] trustedProxies: [172.16.0.0/12] auth: mode: usernamePassword username: local-gateway password: env:PROXY_POOL_GATEWAY_PASSWORD limits: maxConcurrentConnections: 20000 requestsPerMinutePerClient: 60000 retry: maxAttempts: 2 retryMethods: [GET, HEAD] destinationPolicy: denyPrivateNetworks: true denyLoopback: true denyLinkLocal: true denyCIDRs: [169.254.169.254/32] distribution: enabled: true listen: 0.0.0.0:8081 access: allowCIDRs: [172.16.0.0/12] trustedProxies: [172.16.0.0/12] auth: mode: apiKey header: X-API-Key token: env:PROXY_POOL_EXTRACT_TOKEN limits: requestsPerMinute: 6000 requestsPerMinutePerClient: 600 clientIdentification: mode: trustedProxyOrRemoteIP extraction: fulfillment: partial maxCountPerRequest: 100 minRemainingTTL: 30s maxHealthCheckAge: 30s reserveForGateway: 1000 admin: enabled: true listen: 0.0.0.0:8082 access: allowCIDRs: [172.16.0.0/12] auth: mode: apiKey header: X-Admin-Token token: env:PROXY_POOL_ADMIN_TOKEN metrics: enabled: true listen: 0.0.0.0:9090 storage: postgresURL: postgres://proxy_pool:local-only-change-me@postgres:5432/proxy_pool?sslmode=disable redisURL: redis://redis:6379/0 routing: - name: gateway-default enabled: true purpose: gateway upstreams: [provider-a, provider-b] strategy: type: sequential switchAfterEmptyFetch: 5 endBehavior: stayLast onUnavailable: action: reject - name: extract-default enabled: true purpose: extract upstreams: [provider-a, provider-b] strategy: type: sequential switchAfterEmptyFetch: 5 endBehavior: stayLast onUnavailable: action: reject upstreams: provider-a: enabled: true exposure: [gateway, extract] provider: billingMode: fetch protocols: [http] api: url: https://provider-a.invalid/api/proxies method: GET auth: mode: apiKey header: Authorization token: env:PROVIDER_A_TOKEN template: '{{ . }}' proxyAuth: mode: response pool: maxSize: 5000 shrinkDelay: 30s capacity: maxConcurrencyPerProxy: 20 lifecycle: ttl: 5m allocationSafetyMargin: 20s fetch: requestInterval: 1s timeout: 3s maxAttempts: 3 maxInFlight: 1 maxTotal: 100000 maxResponseBytes: 4194304 templateTimeout: 100ms retry: initial: 500ms max: 30s jitter: 20 check: interval: 30s jitter: 20 maxInFlight: 200 timeout: 3s maxAttempts: 2 maxConsecutiveFailures: 3 urls: [https://example.com/] provider-b: enabled: true exposure: [gateway, extract] provider: billingMode: fetch protocols: [http] api: url: https://provider-b.invalid/api/proxies method: GET auth: mode: apiKey header: Authorization token: env:PROVIDER_B_TOKEN template: '{{ . }}' proxyAuth: mode: response pool: maxSize: 5000 shrinkDelay: 30s capacity: maxConcurrencyPerProxy: 20 lifecycle: ttl: 5m allocationSafetyMargin: 20s fetch: requestInterval: 1s timeout: 3s maxAttempts: 3 maxInFlight: 1 maxTotal: 100000 maxResponseBytes: 4194304 templateTimeout: 100ms retry: initial: 500ms max: 30s jitter: 20 check: interval: 30s jitter: 20 maxInFlight: 200 timeout: 3s maxAttempts: 2 maxConsecutiveFailures: 3 urls: [https://example.com/]