Readit News logoReadit News
Someone · 22 days ago
https://man.freebsd.org/cgi/man.cgi?query=sandbox-exec&aprop...:

“The sandbox-exec command is DEPRECATED. Developers who wish to sandbox an app should instead adopt the App Sandbox feature described in the App Sandbox Design Guide”

That still is the case for MacOS 26.3 (https://man.freebsd.org/cgi/man.cgi?query=sandbox-exec&aprop...)

MacOS 10.13.6 is from 2017, so this has been deprecated for almost 10 years.

MillionOClock · 22 days ago
I wonder how many major applications and tools depend on sandbox-exec today despite that depreciation, IIRC I can think of the Codex CLI and Swift Package Manager.
selridge · 22 days ago
Claude, Firefox, safari, chrome, etc etc etc etc

Basically everyone who has to care about security on the Mac.

cpach · 22 days ago
Does anyone have any details regarding the deprecation? I wonder why Apple made this decision.
selridge · 22 days ago
There’s not that much detail. A few comments in 2019 from a DTS person indicated that Apple didn’t really anticipate people shipping on this in volume. My guess is they want to dissuade people from using it.

They can’t immediately just do away with it because a bunch of their first party apps use it (entitlements don’t cut it). It’s a weird space.

VogonPoetry · 22 days ago
"sandbox-exec" is deprecated in the sense of "please don't use this method to run sandboxes" rather than the mechanism going away.

If you are using "sandbox-exec" then you are likely maintaining your own seatbelt profile. Keeping those up to date can be challenging, especially for 3rd parties as any changes to underlying Frameworks and libraries can break a hand crafted profile.

If you are using it to secure your own stuff and accept this and not complain, even for minor SW updates, then you are going to be fine. Don't ship things to 3rd parties without also accepting this. That is what this deprecated means.

TingPing · 22 days ago
I don’t know if there are problems with this tool, but the App Sandbox is very configurable and every app store app is in one. It doesn’t make sense to maintain two different complex sandboxing solutions.
extra88 · 22 days ago
Meh, cron on OS X/macOS has been deprecated for over 20 years.
egorfine · 22 days ago
And its binary is banned on certain macOS installations. I have two identical mac minis with the very same OS version. On one cron runs, on the other the cron binary doesn't run (killed: 9) even if I re-sign the binary in different location with my own codesigning identity. It's that banned.

Dead Comment

ksherlock · 22 days ago

    alias sandbox-no-network='sandbox-exec -p "(version 1)(allow default)(deny network*)"'

pro-tip on alias:

for sh-compliant shells, including a whitespace at the end of the alias string causes the next token to also go through alias expansion. (maybe it would also be a hint to the shell for tab completion as well). This is a perfect example of when, where, and why you would want to do that.

innagadadavida · 22 days ago
I went down the sandbox-exec rabbit hole recently trying to get a “safe shell” for poking at random GitHub projects. I eventually realized I was solving the wrong problem.

For development you usually don’t need a kernel policy language - you mostly want: 1. builds not trashing your real $HOME 2. no dotfiles/config pollution 3. some basic separation if a project does something dumb

A much simpler (and more reliable) alternative on macOS is just a dedicated throwaway user account. macOS already isolates home directories, keychains, and app state per-user, so you get a practical sandbox without fighting SBPL quirks or mysterious denials.

My workflow now: I have a user called rsh. I clone and build everything there. My real home directory stays clean. If a project goes crazy, it only damages /Users/rsh

It also avoids the “1000 hidden files in your home folder” problem that a lot of language ecosystems cause.

Minimal setup :

sudo sysadminctl -addUser rsh -password $(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 16); sudo dseditgroup -o edit -d rsh -t user admin || true; sudo install -d -m 755 -o rsh -g staff /Users/rsh/projects

Then add this alias to your ~/.zshrc command:

alias rsh='sudo -iu rsh /bin/zsh -l'

After that I just run rsh, clone repos into ~/projects, and build there.

viraptor · 22 days ago
> clone repos into ~/projects

Cloning them there means leaving access to your SSH keys, right?

cpach · 19 days ago
No, I don’t think so?

The .git folder will likely contain the URL to the repo, but not any credentials.

ImJasonH · 22 days ago
Both Claude Code and Codex use sandbox-exec with Seatbelt to sandbox execution:

- https://developers.openai.com/codex/security/#os-level-sandb...

- https://code.claude.com/docs/en/sandboxing

bootlooped · 22 days ago
It weirds me out a bit that Claude is able to reach outside the sandbox during a session. According to the docs this is with user consent. I would feed better with a more rigid safety net, which is why I've been explicitly invoking claude with sandbox-exec.

Dead Comment

bdash · 22 days ago
See https://bdash.net.nz/posts/sandboxing-on-macos/ for more details on how sandboxing works on macOS. It touches on how the SBPL Scheme source code is interpreted in userspace to build a bytcode representation of the policy, and the kernel MAC hooks that the Sandbox kernel extension uses for enforcing sandbox policies.
davidcann · 22 days ago
I made a UI for this to run terminal apps, like claude and codex: https://multitui.com
hmokiguess · 22 days ago
I’m impressed really neat work! Why did you opt for closed source?

edit: I don’t have a problem with closed source, but when software is expected to be accountable for my security I get a little paranoid, so was curious about the safety and guarantees here. The UX and everything else looks great

davidcann · 21 days ago
Yeah, that’s understandable. Many open source macOS-only apps seem to get abandoned, so I’m trying to build something sustainable.

It uses only 3 dependencies that are very well known and widely used, so supply chain risk is minimal. That leaves me, the developer, as the main point of trust.

e1g · 22 days ago
I like this! I built something similar for sandboxing CLI agents, and in the repo have a collection of minimal profiles for sandbox-exec to use - https://agent-safehouse.dev/
Tiberium · 22 days ago
Codex already uses sandbox-exec on macOS :)
davidcann · 21 days ago
Yeah, they all do sometimes, but the agent decides what to allow and they can choose to not use it. This gives the user full control of the sandbox and you can run the agent in yolo mode.
ithkuil · 22 days ago
Which terminal do you embed?
davidcann · 21 days ago
SwiftTerm, for not. I may switch to ghostty when their library is ready for embedding.
kilroy123 · 22 days ago
Wow, this looks very nice.
xyzzy_plugh · 22 days ago
It drives me nuts that sandbox-exec has "sandbox" in the name, since it's nothing like a real sandbox, and much closer to something like a high-level seccomp, and not much to do with "App Sandboxes" which is a distinct macOS feature.

IMO a real sandbox let's a program act how it wishes without impacting anything outside the sandbox. In reality many of these tools just cause hard failures when attempting to cross the defined boundaries.

It's also poorly documented and IIRC deprecated. I don't know what is supposed to replace it.

If macOS simply had overlay mounts in a sandbox then it would unlock so much. Compared to Linux containers (docker, systemd, bubblewrap, even unshare) macOS is a joke.

m132 · 22 days ago
> not much to do with "App Sandboxes" which is a distinct macOS feature

The App Sandbox is literally Seatbelt + Cocoa "containers". secinitd translates App Sandbox entitlements into a Seatbelt profile and that is then transferred back to your process via XPC and applied by an libsystem_secinit initializer early in the process initialization, shortly before main(). This is why App Sandbox programs will crash with `forbidden-sandbox-reinit` in libsystem_secinit if you run them under sandbox-exec. macOS does no OS-level virtualization.

bdash · 22 days ago
It is a little more direct than that even. The application's entitlements are passed into the interpretation of the sandbox profile. It is the sandbox profile itself that determines which policies should be applied in the resulting compiled sandbox policy based on entitlements and other factors.

An example from /System/Library/Sandbox/Profiles/application.sb, the profile that is used for App Sandboxed applications, on my system:

  (when (entitlement "com.apple.security.files.downloads.read-only")
        (read-only-and-issue-extensions (home-subpath "/Downloads")))
  (when (entitlement "com.apple.security.files.downloads.read-write")
        (read-write-and-issue-extensions (home-subpath "/Downloads")))
  (when (or (entitlement "com.apple.security.files.downloads.read-only")
            (entitlement "com.apple.security.files.downloads.read-write"))
        (allow process-exec (home-subpath "/Downloads")))

gobdovan · 22 days ago
What you're describing is a resource virtualization with transactional reconciliation instead of program isolation in the mediation sense (MAC/seccomp-style denial).

To let a program act as it wishes, ideally every security-relevant mutable resource must be virtualized instead of filtered. Plus, FS is only one of the things that should be sandboxed. You should also ideally virtualize network state at least, but ideally also process/IPC namespaces and other such systems to prevent leaks.

You need to offer a promotion step after the sandbox is over (or even during running if it's a long-running program) exposing all sandbox's state delta for you to decide selective reconciliation with the host. And you also must account for host-side drift and TOCTOU hazards during validation and application

I'm experimenting with implementing such a sandbox that works cross-system (so no kernel-level namespace primitives) and the amount necessary for late-bound policy injection, if you want user comfort, on top of policy design and synthetic environment presented to the program is hair-pulling.

m132 · 22 days ago
> I'm experimenting with implementing such a sandbox that works cross-system (so no kernel-level namespace primitives) and the amount necessary for late-bound policy injection, if you want user comfort, on top of policy design and synthetic environment presented to the program is hair-pulling.

Curious, if this is cross-platform, is your design based on overriding the libc procedures, or otherwise injecting libraries into the process?

Also obligatory https://xkcd.com/2044/

simonw · 22 days ago
Sandbox-exec covers everything I personally expect from a sandbox:

- controls which files the process can read and write

- controls what network access the process is allowed

_wire_ · 22 days ago
> If macOS simply had overlay mounts in a sandbox then it would unlock so much. Compared to Linux containers (docker, systemd, bubblewrap, even unshare) macOS is a joke.

You'll want to look into Homebrew (or Macports) for access to the larger world

TingPing · 22 days ago
They are discussing a Linux kernel feature. Docker/Podman on macOS launch a virtual machine to function.
lyaocean · 22 days ago
I'd add one warning for folks who haven't used it before: a tiny typo in the profile can turn into confusing runtime failures later, far away from the command that triggered them. The tool is useful, but the feedback loop is rough.