Skip to content

Allow webrtc connection for products - #399

Merged
ERussel merged 9 commits into
mainfrom
chore/open-webrtc
Aug 17, 2026
Merged

Allow webrtc connection for products#399
ERussel merged 9 commits into
mainfrom
chore/open-webrtc

Conversation

@ERussel

@ERussel ERussel commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Products need WebRTC (RTCPeerConnection) inside the iOS/Android host. The
earlier approach in #379 tried
to gate it behind an app-level permission through the __container__ bridge,
but that gating did not hold up, so it is not the path forward.

Instead, the lockdown container now leaves RTCPeerConnection available to
products rather than deleting it. We accept that leaving RTCPeerConnection available also permits unprompted ICE gathering to arbitrary STUN/TURN hosts over UDP as a tradeoff to allow products to use WebRTC connection. Access to the camera and microphone stays protected by the operating system: the user still sees the native permission
prompts before any media is captured.

SOLUTION

  • js/container — the TrUAPI-mode lockdown no longer removes
    window.RTCPeerConnection. Products can construct peer connections directly;
    camera and microphone capture (getUserMedia) continues to trigger the
    native OS permission request. The vendored
    ios/truapi-host/.../Resources/truapi-container.js bundle is regenerated to
    match.
  • Playground — the WebRTC method requests camera and microphone (device
    permissions) through TrUAPI, then runs getUserMedia +
    RTCPeerConnection.createOffer. It appears in the method browser and the
    diagnosis so the flow can be exercised end to end. It no longer requests a
    separate WebRTC remote permission.

CONTEXT

@ERussel
ERussel requested review from a team August 14, 2026 13:03
@ERussel
ERussel force-pushed the chore/open-webrtc branch from 83a0f2e to 6379f5d Compare August 14, 2026 13:42
@filvecchiato

Copy link
Copy Markdown
Collaborator

Reviewed with the container's other lockdowns in mind. The same-origin fetch allowance plus products being served from their own origin (ios/truapi-host/README.md:268) means a data channel adds NAT traversal rather than a new capability, so the transport question seems fine to me. Three things that are not covered by the camera/microphone argument:

  • ICE gathering is unprompted reach to an arbitrary host. new RTCPeerConnection({iceServers:[{urls:"stun:…"}]}) followed by setLocalDescription(await createOffer()) sends UDP to whatever server the product names — no media, no signalling, no prompt, and nothing the host can observe. The public IP is not the interesting part (the product's own backend already sees it, and local IPs are mDNS-hidden without media permission); the interesting part is that this is exactly the arbitrary-host reach the same-origin fetch gate denies 40 lines above. There is no CSP anywhere in the repo to constrain it, and since products serve their own HTML there is nowhere to inject one. Worth stating in the SUMMARY as accepted rather than leaving it implied by "the OS protects capture".
  • RemotePermission::WebRtc becomes fail-open. v01::permissions.rs:57 is still a live, promptable, persistable permission, and its only non-test call sites are products voluntarily calling request_remote_permission — so nothing enforces it now. RFC-0002:51 also still says WebRTC "should be handled by the Host's sandbox implementation". Either drop the variant or record that it is advertised and unenforced.
  • The new diagnosis row cannot pass unattended. WebRTC/peer_connection is appended unconditionally but is in neither SKIPPED_SERVICES (auto-test.ts:24) nor expectedHostGaps (tests/e2e/dotli-diagnosis.ts:59-79), and the headless context grants camera + clipboard only, never microphone, with no capture device — so the dotli harness throws on it. On iOS the documented integration builds its WKWebView with no WKUIDelegate, so getUserMedia is denied until #1351 lands. SKIPPED_SERVICES looks like the right home for it.

Verified separately: a rebuild of js/container reproduces the committed truapi-container.js exactly — RTCPeerConnection gone, XHR/EventSource deletions intact, no unrelated drift. Note no CI job rebuilds and diffs that bundle, so a stale one would merge unnoticed.

@filvecchiato filvecchiato left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one minor nit: RFC-0002 states something that this PR now (obviously) contradicts. maybe a follow-up issue should be open if not already open

@ERussel

ERussel commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

one minor nit: RFC-0002 states something that this PR now (obviously) contradicts. maybe a follow-up issue should be open if not already open

I think that we should keep RFC as it is. In the target solution we still want to gate WebRTC properly but that requires proper planing beforehand

@ERussel
ERussel added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit b82384e Aug 17, 2026
15 checks passed
@ERussel
ERussel deleted the chore/open-webrtc branch August 17, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants