Skip to content

Use the CEF sandbox on macOS (obs-rust/obs-studio#1092) - #12

Merged
zackees merged 2 commits into
obs-rust:masterfrom
vpacher:feat/1092-macos-sandbox
Oct 25, 2026
Merged

zackees merged 2 commits into
obs-rust:masterfrom
vpacher:feat/1092-macos-sandbox

Conversation

@vpacher

@vpacher vpacher commented Oct 25, 2026

Copy link
Copy Markdown
Member

Refs obs-rust/obs-studio#1092

What and why

On macOS the browser source ran without the CEF sandbox: browser-sandbox had no probe for macOS, so settings.no_sandbox stayed true (#1092). Measured on macOS 26.7.1, Apple Silicon, with CEF 7871: with the helpers sandboxed, browser sources work, including HTTPS fetch, WebAudio, and WebM recording and playback.

  • Each helper sandboxes itself before the framework loads (CefScopedSandboxContext, as in CEF's sample helper), unless OBS passed --no-sandbox.
  • The helper loads libcef_sandbox.dylib from the framework next to it (<app>/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/). ProbeSandbox() on macOS checks that file, with the framework found from the executable's path, so the probe and the helper agree. (dladdr() on cef_version_info, as on Linux, does not point into the framework on macOS.)
  • With the library: mode Seatbelt, "CEF sandbox on". Without it a sandboxed helper would exit and no browser source would render, so OBS runs without the sandbox and shows the fallback warning (SandboxFallback.Message.NoSandboxLibrary, new string in en-US.ini).

Linux is unchanged; Windows still has no probe (obs-rust/obs-studio#2379).

RED → GREEN

  • RED 820ca85: the probe gets macOS facts (macos, sandbox_library) and the mode Seatbelt; tests/sandbox-decision.cpp gets 6 macOS cases (decision, fallback, warning; with and without the library). 5 fail: DecideSandbox() treated the macOS probe like a Linux one.
  • GREEN 82cab3b: all 28 cases pass.
  • Real app (macOS 26.7.1, Apple Silicon, ad-hoc signed, local build), with a page that turns green only if HTTPS fetch, WebAudio and WebM recording and playback all work:
    • with libcef_sandbox.dylib: "CEF sandbox on: libcef_sandbox.dylib is in the CEF framework", all six helpers sandboxed (sandbox_check(): the GPU process, three utility processes, two renderers), the page green;
    • with the library moved out of the app: the fallback warning, the helpers run without the sandbox, the page green.
  • Not tested: an Intel Mac (none available), and a Developer ID signed build (the releases are ad-hoc signed until macos: Releases are still not signed or notarized: configure the release credentials obs-studio#2383).

AI note: Claude Code (Claude Opus 5.5) wrote the change, the tests and this text under the submitter's direction, and ran the tests above on the submitter's machine.

vpacher and others added 2 commits October 25, 2026 13:35
On macOS the CEF sandbox works with CEF 7871 (measured for
obs-rust/obs-studio#1092 on macOS 26.7.1, Apple Silicon: with the
helpers sandboxed, a local page, HTTPS fetch, WebAudio and WebM video all
work). Each helper loads libcef_sandbox.dylib from the framework's
Libraries; a helper that cannot exits, and no browser source renders.

The probe gets macOS facts (macos, sandbox_library) and a mode
Seatbelt. sandbox-decision.cpp: with the library, Seatbelt and no
warning; without it, off with the fallback warning and its own message
(SandboxFallback.Message.NoSandboxLibrary). DecideSandbox() still treats
the macOS probe like a Linux one, so 5 of the 6 macOS cases fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each helper now sandboxes itself before the framework loads
(CefScopedSandboxContext, as in CEF's sample helper), unless OBS passed
--no-sandbox. OBS turns the sandbox on when the framework next to the
helpers has Libraries/libcef_sandbox.dylib, where each helper loads it
from: ProbeSandbox() on macOS checks <app>/Contents/Frameworks/Chromium
Embedded Framework.framework, found from the executable's path. Without
the library a sandboxed helper would exit and no browser source would
render, so OBS runs without the sandbox then and shows the fallback
warning (SandboxFallback.Message.NoSandboxLibrary).

sandbox-decision.cpp: all cases pass. Real app on macOS 26.7.1, Apple
Silicon, ad-hoc signed, with a page that needs HTTPS fetch, WebAudio and
WebM recording and playback: with the library, "CEF sandbox on", all six
helpers sandboxed, the page works; with the library moved out, the
fallback warning, the helpers run without the sandbox, the page works.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@zackees zackees left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed. The macOS helper code stays inside the existing __APPLE__ && !ENABLE_BROWSER_LEGACY block. CefScopedSandboxContext runs before LoadInHelper, as in CEF's sample helper, and --no-sandbox turns it off. The probe and the helper look in the same place (Frameworks/…/Libraries/libcef_sandbox.dylib). RED → GREEN adds 6 macOS decision, fallback and warning cases, and the fallback string is added to en-US.ini. The real-app check covers both the case with the library and the case without it. Linux behaviour is unchanged. LGTM.

@zackees
zackees merged commit 63fd678 into obs-rust:master Oct 25, 2026
1 check passed
@obs-rust-project-manager obs-rust-project-manager Bot moved this from In review to Done in obs-rust Multiview Oct 25, 2026
MCPVOT pushed a commit to MCPVOT/obs-studio that referenced this pull request Oct 25, 2026
…rust#2402)

obs-rust/obs-browser#11: on macOS, do not hand BrowserInit() to the Qt
main thread once its loop has stopped, so a first browser source created
off the main thread while OBS quits no longer hangs it (obs-rust#2391).

obs-rust/obs-browser#12: browser sources and panels use the CEF sandbox
on macOS, with libcef_sandbox.dylib from the CEF framework; without it,
the helpers run unsandboxed and OBS shows the fallback warning (obs-rust#1092).

docs/features.md: the sandbox line covers Linux and macOS, the obs-rust#2387
line names the quit case.

Fixes obs-rust#2391
Refs obs-rust#1092

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants