fix(sandbox): allow the FSEvents Mach service on macOS - #7
Open
paveq wants to merge 1 commit into
Open
Conversation
Every file watcher on macOS reaches fseventsd through the `com.apple.FSEvents` Mach service, which was missing from the `mach-lookup` allowlist in [emit_common_rules](src/sandbox.rs#L484). The resulting failures are unrecognisable as sandbox denials: libuv reports a failed `FSEventStreamStart` as `EMFILE: too many open files, watch` (so `node --watch`, nodemon and vite look like they hit a descriptor limit, even with `ulimit -n` at 1048576), and Bun reports `error: Error starting FSEvents stream`. Confirmed with `bootstrap_look_up` from inside a sandboxed session: `com.apple.FSEvents` returns 1100 (permission denied) while allowlisted services such as `com.apple.trustd.agent` return success. The grant is notification-only — reading a changed file still goes through the filesystem rules — but an event stream rooted outside the sandbox does report paths of files the process cannot open. That metadata channel is noted in [SECURITY.md](SECURITY.md) as the cost of working dev servers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
File watchers do not work inside the macOS sandbox, and the errors do not look like sandbox denials:
node --watch(and nodemon, vite):Error: EMFILE: too many open files, watch—errno: -24, even withulimit -nat 1048576.error: Error starting FSEvents stream.Both are the same failure. libuv's
uv__fsevents_initreturnsUV_EMFILEwhenFSEventStreamStartfails, so the descriptor-exhaustion message is a red herring; the stream never started because the process could not reachfseventsd.Cause
com.apple.FSEventswas missing from themach-lookupallowlist inemit_common_rules. Confirmed from inside a sandboxed session withbootstrap_look_up:Fix
Add
com.apple.FSEventsto the shared allowlist (tool and agent profiles both), with tests asserting it is present in each, and a note in SECURITY.md.Security trade-off
The grant is notification-only — reading a changed file still goes through the filesystem rules. It does widen metadata disclosure: an event stream rooted outside the sandbox reports the paths of files the process cannot open. SECURITY.md records this as the accepted cost of working dev servers.
Not covered here
Phoenix live-reload's
Can't find executable mac_listener/{:error, :fs_mac_bootstrap_error}is a separate issue — thefsdependency'smac_listenerhelper binary is not on the path it expects. Once it does run, this change is what lets it talk to fseventsd.Testing
cargo test --libcould not be run: this sandbox has neither read nor write access to~/.cargo, so cargo cannot resolve the registry. The two new assertions are pure string checks over the generated SBPL and need a run on a host with cargo access before merge.