LogoBirchdocs

Sandboxing

Apple has two different systems for reducing privileges of macOS apps to improve security for users: the App Sandbox and the Hardened Runtime. While the Hardened Runtime is a requirement for distributing outside of the Mac App Store, it is currently optional for the Mac App Store itself.

Which should I enable?

I experimented with these options for an Electron app distributed on the Mac App Store. While I was able to enable App Sandbox, enabling the Hardened Runtime as well just led to the app crashing at launch. This mirrors the experience of another Electron user who reported that he'd had no luck enabling both App Sandbox and Hardened Runtime. In the end, he (and thus I also) went with:

PlatformApp SandboxHardened Runtime
Mac App Store (mas)enableddisabled
Third-party distribution (darwin)disabledenabled

For now, the Electron community does not seem to have discovered a way to enable both, and even Visual Studio Code hasn't turned on both (they only do self-distribution, and just enable the Hardened Runtime but not the App Sandbox there).

How do they differ?

Equivalent entitlements may be named somewhat differently between the two systems. Looking at Chromium's entitlements, for example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.device.audio-input</key>
	<true/>
	<key>com.apple.security.device.bluetooth</key>
	<true/>
	<key>com.apple.security.device.camera</key>
	<true/>
	<key>com.apple.security.device.print</key>
	<true/>
	<key>com.apple.security.device.usb</key>
	<true/>
	<key>com.apple.security.personal-information.location</key>
	<true/>
	<key>com.apple.security.personal-information.photos-library</key>
	<true/>
</dict>
</plist>

Here, they use com.apple.security.device.audio-input, which is a Hardened Runtime entitlement that allows capturing audio from the microphone.

However, when using App Sandbox, the equivalent entitlement would be com.apple.security.device.microphone.

Gotchas when shipping an Electron app to the Mac App Store

Electron users have found that the following changes need to be made to default.mas.plist, as otherwise the app would simply crash at startup:

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
   <dict>
     <key>com.apple.security.app-sandbox</key>
     <true/>
     <key>com.apple.security.files.user-selected.read-write</key>
     <true/>
     <key>com.apple.security.files.bookmarks.app-scope</key>
     <true/>
     <key>com.apple.security.network.client</key>
     <true/>
     <key>com.apple.security.print</key>
     <true/>
     <key>com.apple.security.device.camera</key>
     <true/>
     <key>com.apple.security.device.microphone</key>
     <true/>
     <key>com.apple.security.device.usb</key>
     <true/>
+    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
+    <true/>
+    <key>com.apple.security.cs.allow-jit</key>
+    <true/>
   </dict>
 </plist>

Technically, I think we only need one of the two entitlements (as they are tiered and one implies the other – as I believe Quinn explained on the Apple Developer Forums), but I've not taken the time to work out the minimum viable config.