feat(router): add relayfile-cloud auth-aware Nango webhook routing#6
feat(router): add relayfile-cloud auth-aware Nango webhook routing#6khaliqgant wants to merge 1 commit into
Conversation
Ports the auth-classification logic from cloud PR #2472 into the agentrelay.com apex router. When the ROUTER_CONFIG `WEBHOOK_ORIGIN` flag is set to "relayfile-cloud", allowlisted non-lifecycle Nango ingest events (forward/sync/webhook for known providerConfigKeys) are forwarded to the RELAYFILE_CLOUD_WORKER service binding; auth/lifecycle events always fall through to cloud-web so handleAuthEvent keeps running. Dormant until the flag is set. Changes: - Add RELAYFILE_CLOUD_WORKER binding + RELAYFILE_CLOUD_ORIGIN var to wrangler.jsonc - Add WEBHOOK_ORIGIN_RELAYFILE_CLOUD, RELAYFILE_CLOUD_FORWARDED_*, lifecycle/ingest/provider-allowlist constants to index.ts - Add isRecord, readString, readNangoWebhookType, readNangoProviderConfigKey, isRelayfileCloudNangoIngestRequest, isRelayfileCloudForward, shouldUseNangoRelayfileCloudRoute, shouldUseRelayfileCloudWebhook, buildRelayfileCloudWebhookRequest - Update shouldUseCloudWebWorker to exclude relayfile-cloud ingest - Add relayfile-cloud routing branch in fetch handler (mirrors the webhook-worker branch structure: service binding then origin URL) - Add vitest.config.ts so the router test suite runs standalone - Add 4 new tests covering: ingest routing, lifecycle fallback to cloud-web, non-allowlisted provider fallback, and loop-break header Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces routing support for forwarding specific Nango webhook ingest requests to relayfile-cloud (via either a service binding or a fallback origin) when the WEBHOOK_ORIGIN flag is configured. It includes parsing logic to identify allowlisted ingest requests while ensuring lifecycle events continue to route to cloud-web, along with corresponding unit tests and configuration updates. Feedback is provided regarding an optimization opportunity in router/index.ts to avoid redundant cloning and parsing of the request body by caching the parsed result and immediately returning false for non-POST requests.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| async function isRelayfileCloudNangoIngestRequest(request: Request): Promise<boolean> { | ||
| let body: unknown; | ||
| try { | ||
| body = await request.clone().json(); | ||
| } catch { | ||
| return false; | ||
| } | ||
| if (!isRecord(body)) return false; | ||
| const type = readNangoWebhookType(body); | ||
| if (!type || RELAYFILE_CLOUD_NANGO_LIFECYCLE_TYPES.has(type)) return false; | ||
| if (!RELAYFILE_CLOUD_NANGO_INGEST_TYPES.has(type)) return false; | ||
| const providerConfigKey = readNangoProviderConfigKey(body); | ||
| return providerConfigKey | ||
| ? RELAYFILE_CLOUD_NANGO_PROVIDER_CONFIG_KEYS.has(providerConfigKey) | ||
| : false; | ||
| } |
There was a problem hiding this comment.
The isRelayfileCloudNangoIngestRequest function is called twice for every matching request (once during the shouldUseCloudWebWorker check and once in the main fetch routing logic). This causes the request body to be cloned and parsed as JSON twice, which introduces unnecessary CPU and memory overhead on the hot path.
Additionally, non-POST requests (e.g., GET or OPTIONS) sent to this path will still attempt to clone and parse the body, throwing an exception that is caught but still wastes resources.
We can optimize this by:
- Returning
falseimmediately if the request method is notPOST. - Caching the parsed result in a
WeakMapkeyed by theRequestobject to avoid double-parsing.
const ingestRequestCache = new WeakMap<Request, Promise<boolean>>();
async function isRelayfileCloudNangoIngestRequest(request: Request): Promise<boolean> {
if (request.method !== "POST") {
return false;
}
let promise = ingestRequestCache.get(request);
if (!promise) {
promise = (async () => {
let body: unknown;
try {
body = await request.clone().json();
} catch {
return false;
}
if (!isRecord(body)) return false;
const type = readNangoWebhookType(body);
if (!type || RELAYFILE_CLOUD_NANGO_LIFECYCLE_TYPES.has(type)) return false;
if (!RELAYFILE_CLOUD_NANGO_INGEST_TYPES.has(type)) return false;
const providerConfigKey = readNangoProviderConfigKey(body);
return providerConfigKey
? RELAYFILE_CLOUD_NANGO_PROVIDER_CONFIG_KEYS.has(providerConfigKey)
: false;
})();
ingestRequestCache.set(request, promise);
}
return promise;
}|
Preview deployed!
This is a Cloudflare Workers preview version of this PR's build. |
|
Both pass; working tree has only the untracked Let me write up the review. Review: PR #6 — relayfile-cloud auth-aware Nango webhook routingI read What the PR doesAdds a third Nango-webhook destination ("relayfile-cloud") to the Cloudflare router. When the Verification of correctness / safety
I made no edits — there were no lint/format/typo issues to mechanically fix, and the logic is sound, so nothing warranted an auto-edit. Addressed comments
Advisory Notes
The change is well-scoped, tested, and verified green locally. The remaining items are advisory judgment calls for a human, and I cannot confirm the actual GitHub CI/merge status from this sandbox, so I am not declaring it merge-ready. |
Summary
WEBHOOK_ORIGINflag ="relayfile-cloud", allowlisted non-lifecycle Nango ingest events (forward/sync/webhookfrom knownproviderConfigKeys) are forwarded toRELAYFILE_CLOUD_WORKERauth,connection.created) always fall through to cloud-web —handleAuthEventis load-bearing and must stay in cloudWEBHOOK_ORIGINis explicitly flipped to"relayfile-cloud"in ROUTER_CONFIG KVChanges
router/wrangler.jsonc: addRELAYFILE_CLOUD_WORKERservice binding +RELAYFILE_CLOUD_ORIGINvarrouter/index.ts: add constants, auth-classification helpers,shouldUseNangoRelayfileCloudRoute,shouldUseRelayfileCloudWebhook,buildRelayfileCloudWebhookRequest, relayfile-cloud routing branch infetch(); updateshouldUseCloudWebWorkerto exclude relayfile-cloud ingest pathrouter/test/webhook-routing.test.ts: 4 new tests (ingest routed to relayfile-cloud, lifecycle falls back to cloud-web, non-allowlisted provider falls back to cloud-web, loop-break header bypasses relayfile-cloud)router/vitest.config.ts: new — scopes vitest totest/**so the suite runs standalone without the parent workspace config interferingParity with cloud #2472
Mirrors
cloud/packages/router/index.tsfromorigin/worker/nango-auth-aware-routerexactly:RELAYFILE_CLOUD_NANGO_LIFECYCLE_TYPES,INGEST_TYPES,PROVIDER_CONFIG_KEYSsetsx-cloud-webhook-relayfile-cloud-forwarded: relayfile-cloud)RELAYFILE_CLOUD_ORIGINURL when service binding is absentdeploy-router.ymltrigger onrouter/**push tomain)Test plan
npm --workspace router run test— 65 tests pass (8 new)npm --workspace router run typecheck— clean🤖 Generated with Claude Code
Summary by cubic
Adds auth-aware routing for Nango webhooks to relayfile-cloud in the apex router. Enabled only when
WEBHOOK_ORIGIN=relayfile-cloud; allowlisted ingest events route toRELAYFILE_CLOUD_WORKER, while lifecycle/auth events continue to cloud-web.forward,sync,webhook) for known providerConfigKeys; lifecycle types (auth,connection.created) always go to cloud-web.x-cloud-webhook-relayfile-cloud-forwardedand keeps HMAC-safe body handling (clone to inspect, forward original).RELAYFILE_CLOUD_WORKERservice binding andRELAYFILE_CLOUD_ORIGINfallback URL; excludes relayfile-cloud ingest from the cloud-web default path.vitestconfig scoped torouter/test.Written for commit 6f92571. Summary will update on new commits.