I'm working on a multi-process macOS application (based on Chromium/Electron) that uses Mach ports for inter-process communication between the main app and its helper processes.
Background
I have an MAS build working successfully via TestFlight for internal testing. However, public TestFlight testing requires Apple review, and while waiting for that review, I wanted to provide a
directly distributable build for external testers. I attempted to create a Developer ID signed build with App Sandbox enabled, expecting it to behave similarly to the MAS build.
The Problem
With App Sandbox enabled (com.apple.security.app-sandbox) and identical entitlements, I observe different behavior depending on the signing certificate:
Apple Distribution certificate: App launches successfully, mach-register and mach-lookup work
Developer ID certificate: App crashes at launch, mach-register is denied by sandbox
The Console shows this sandbox violation for the Developer ID build:
Sandbox: MyApp(13605) deny(1) mach-register XXXXXXXXXX.com.mycompany.myapp.MachPortRendezvousServer.13605
The crash occurs when the app calls bootstrap_check_in() to register a Mach service for child process communication.
What I've tried
Adding com.apple.security.temporary-exception.mach-register.global-name with wildcard pattern XXXXXXXXXX.com.mycompany.myapp.MachPortRendezvousServer.* to the main app's entitlements - this resolved the mach-register denial.
However, helper processes then fail with mach-lookup denial. Adding com.apple.security.temporary-exception.mach-lookup.global-name with the same wildcard pattern to the main app's entitlements (for inheritance) does not work.
Analysis of /System/Library/Sandbox/Profiles/application.sb
I examined macOS's App Sandbox profile and found that mach-register.global-name supports wildcard patterns via select-mach-filter:
(sandbox-array-entitlement
"com.apple.security.temporary-exception.mach-register.global-name"
(lambda (name)
...
(let ((mach-filter
(select-mach-filter name global-name-prefix global-name)))
(allow mach-register mach-filter))))
But mach-lookup.global-name does not - it only accepts exact names:
(sandbox-array-entitlement
"com.apple.security.temporary-exception.mach-lookup.global-name"
(lambda (name) (allow mach-lookup (global-name name))))
Since the Mach service name includes the PID (e.g., ...MachPortRendezvousServer.13605), it's impossible to specify exact names in entitlements.
I also verified that com.apple.security.application-groups grants mach-register and mach-lookup only for service names prefixed with the group ID (e.g., group.com.mycompany.myapp.), which
doesn't match the TEAMID.bundleid. prefix used by Chromium's MachPortRendezvousServer.
My questions
What mechanism allows Apple Distribution signed apps to use mach-register and mach-lookup for these service names without temporary exceptions? I don't see any certificate-based logic in application.sb.
Is there a way to achieve the same behavior with Developer ID signing for testing purposes?
Related threads
https://developer.apple.com/forums/thread/747005
https://developer.apple.com/forums/thread/685601
https://developer.apple.com/forums/thread/128714 (confirms temporary-exception can be used freely for Developer ID apps)
Environment
macOS 15.6 (Sequoia)
Xcode 16.4
Both certificates from the same Apple Developer account
Topic:
App & System Services
SubTopic:
General
Tags:
App Store
Entitlements
App Sandbox
Developer ID