feat(w1 slice-2b/O1): INERT CF Live Output RTMP restream + SSRF-at-connect (wre#287) - #320
Conversation
…recheck (INERT, wre#287)
What: implements the concrete CfStreamEgressClient adapter
(egress-cf-stream-live-output-client.ts) that turns an already-ingested
Zoom CF Live Input into a live simulcast to a customer's external RTMP
destination via CF's real `POST /accounts/{accountId}/stream/live_inputs/
{liveInputId}/outputs` endpoint, reusing cf-stream-live-client.ts's
account-id + bearer-token auth pattern. Fails closed (typed error, never
throws) on a non-2xx CF reply.
Closes the SSRF-only-at-create gap: adds assertDestinationSafeAtConnect
(egress-arm.ts), which re-runs validateDestinationUrl immediately before
any outbound provision/dial, and wires it into a new
armExternalRtmpRestream arm path: resolveDestinationForArm -> refuse if
null (404) -> SSRF-at-connect -> refuse if unsafe (403) -> provisionOutput.
A destination that resolved to a public IP at create-time but rebinds to
a private/metadata/CGNAT IP by connect-time is now refused, not
provisioned.
INERT: armExternalRtmpRestream requires BOTH EGRESS_ROUTER_ENABLED and
EGRESS_DEST_MGMT_ENABLED armed (default OFF); either flag off refuses
before any lookup. No existing call site invokes it, so prod is
byte-identical.
Consumes resolveDestinationForArm (egress-destinations.ts, wre#289) for
the decrypted destination. Part of Zoom Live Media epic wave-zoom#46.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_e616e710-1ec8-4192-b9fc-5677db5ce8c9) |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 36 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…int + kind guard + resolve try/catch MEDIUM: CfStreamEgressLiveOutputClient.provisionOutput now re-runs validateDestinationUrl (SSRF-at-connect, fail-closed on reject or throw) before any CF output create — the shared chokepoint both CfStreamPassthroughEgressBackend.provision and armExternalRtmpRestream funnel into, so the passthrough path is covered even though it never called assertDestinationSafeAtConnect itself. LOW: armExternalRtmpRestream now asserts dest.kind === "rtmp" and refuses (400) a mismatched destination before treating it as RTMP. LOW: armExternalRtmpRestream now wraps resolveDestinationForArm in try/catch and refuses (500, fail-closed) on throw, matching its documented "never throws" contract. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Summary
CfStreamEgressClientadapter (egress-cf-stream-live-output-client.ts): calls CF's realPOST /accounts/{accountId}/stream/live_inputs/{liveInputId}/outputswith{url, streamKey}, derived live-input uid from the bridgedcfstream:{uid}sessionId, fail-closed typed errors (no throw into media path).assertDestinationSafeAtConnect(egress-arm.ts) re-runsvalidateDestinationUrlimmediately before any outbound provision/dial.armExternalRtmpRestreamarm path:resolveDestinationForArm-> refuse (404) if null -> SSRF-at-connect -> refuse (403) if unsafe ->provisionOutput.EGRESS_ROUTER_ENABLEDandEGRESS_DEST_MGMT_ENABLEDarmed (default OFF). No call site wires it in yet — prod byte-identical.resolveDestinationForArmfrom wre#289 (feat(w1): external egress destination mgmt + SSRF guard + key encryption (O3, #17, #18) #316/feat(w1 slice-1b): INERT emitEgressLegUsage egress-leg metering #318, already on main).Test plan
npx tsc --noEmit— 0 errorsnpx vitest run— 1445/1445 passing (full suite, no regressions)🤖 Generated with Claude Code
Note
Medium Risk
Touches egress connect-time SSRF and outbound CF provisioning for user-supplied RTMP URLs, but stays inert without both flags and has no production call site yet.
Overview
Adds inert-by-default wiring to simulcast an already-ingested Cloudflare Stream live input to a customer RTMP destination (YouTube/Twitch/custom), gated on both
EGRESS_ROUTER_ENABLEDandEGRESS_DEST_MGMT_ENABLED. Nothing in prod calls it yet.egress-arm.tsintroducesassertDestinationSafeAtConnect(re-runsvalidateDestinationUrlright before dial/provision to close DNS-rebind after create-time checks) andarmExternalRtmpRestream: resolve org-scoped destination → SSRF-at-connect → typedprovisioned/refusedoutcomes (404/403/CF errors), no throws into the media path.egress-cf-stream-live-output-client.tsis the concreteCfStreamEgressClientthat POSTs CF Stream live outputs: derives live-input id fromcfstream:{32-hex}session ids, splits combined RTMP URLs into CF’s{url, streamKey}body, fail-closed on bad input or API errors.Vitest covers DNS-rebind refusal, flag-off inert behavior, org/destination failures, and mocked CF request shape.
Reviewed by Cursor Bugbot for commit 94e1aae. Configure here.
Summary by cubic
Adds external RTMP restreaming via Cloudflare Stream Live Output and closes the DNS-rebind gap by rechecking destinations at connect time, centralized at the CF-output chokepoint. Inert behind
EGRESS_ROUTER_ENABLEDandEGRESS_DEST_MGMT_ENABLED. Addresses wre#287 and sec-review #320.New Features
CfStreamEgressLiveOutputClient: calls CloudflarePOST /accounts/{accountId}/stream/live_inputs/{liveInputId}/outputs, derivesliveInputIdfromcfstream:{uid}, splits combinedrtmp://.../app/streamKey, returns typed errors on non-2xx.assertDestinationSafeAtConnect: re-runsvalidateDestinationUrlright before provisioning to block DNS-rebinds.armExternalRtmpRestream: resolves the org-scoped destination, rechecks SSRF, then provisions via the client; typed outcomes; INERT unless both flags are on.Bug Fixes
CfStreamEgressLiveOutputClient.provisionOutputso both passthrough and O1 arm paths cannot provision if the resolved IP is unsafe.armExternalRtmpRestream(non-rtmprefused with 400).resolveDestinationForArmin try/catch; failures now refuse with 500 (fail-closed), not throws.Written for commit 06c4207. Summary will update on new commits.