How to use CFMessagePort in a Sandbox App when App Group naming convention is not possible?

I am working on an App and I am in the process of adding Syphon support.

Syphon uses CFMessagePort for IPC and passing of FrameBuffer data (MTLTexture) between apps - and is widely used in the professional video app and video production space.

What I have noticed is that when the App is built as a Sandbox app, during the Syphon initialization, I see the following error message in the log:

*** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x8703, name = 'info.v002.Syphon.D2499DBD-93AE-4CEA-B21F-FF356DCC069D'
See /usr/include/servers/bootstrap_defs.h for the error codes.

Syphon uses the "info.v002.Syphon.UUID" naming convention to identify IPC Syphon servers, so I don't think I can use the App Groups naming convention for Sandbox support.

I have a very simple example app on github that publishes SpriteKit frames as a Syphon Server. To see the issue, simply enable App Sandbox for the build, and run the app. You should see the error message in the log and no data appears in any Syphon Client (I use Syphon Recorder for testing - available at syphon.github . io

I am looking for other options to enable CFMessagePorts on a Sandbox App.

Answered by DTS Engineer in 788783022
My app is already shipping on the Mac App Store

Yeah, that makes things tricky. I don’t see any way to implement the IPC protocol as you’ve described it in a sandboxed app. Given that, I see two possible paths forward:

  • You could build some sort of adaptor that bridges between your app and this protocol, and distribute that directly using Developer ID signing.

  • You could engage with the Syphon community to rework or extend the protocol into something that’s compatible with the App Sandbox.

Both of these are tricky. The first has potential App Review implications. The second assumes that it’s possible to design such a protocol, and then you have to get other apps to update.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

This is going to be tricky, but it might not be impossible (-:

It seems like Syphon is a peer-to-peer thing, that is, there’s no centralised daemon or agent that the user has to install. Is that correct?

If so, how do Syphon peers discover other Syphon peers?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

It seems like Syphon is a peer-to-peer thing, that is, there’s no centralised daemon or agent that the user has to install. Is that correct? If so, how do Syphon peers discover other Syphon peers?

I am not too familiar with the internals of Syphon - but after looking over the source code (it's open source) - it looks like it is using NSDistributedNotificationCenter as a centralized messaging system for discovery and IPC setup. In Syphon lingo, a server is an app that publishes frames - a client is an app that can consume frames from any of the servers currently running.

I believe it goes something like this:

What I have found is that Syphon clients are sensitive to the CFMessagePort naming convention, i.e., if you mess with this naming convention at all, discovery stops working.

So who sends the notification? The server, when it start ‘advertising’? Or the clients when they start ‘browsing’?

And do the notifications have a payload?

By way of context, there are two concerns here:

  • Mach service names — used by the Mach bootstrap service, XCP, and CFMessagePort — are restricted in a sandboxed context. Specifically, the service name must be prefixed by an app group ID that the app claims via the app group entitlement [1].

  • The App Sandbox allows distributed notifications but disallows any payload. See the discussion in Protecting user data with App Sandbox.

Oh, one last thing: Are you concerned about sandboxing because you want to ship on the Mac App Store? Or just because it’s the right thing to do?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Note that App groups are tricky on macOS. See App Groups: macOS vs iOS: Fight!.

So who sends the notification? The server, when it start ‘advertising’? Or the clients when they start ‘browsing’?

Both. When a server instance is started, it sends a ServerAnnounce notification (this has a payload). When a client is started, it sends a ServerAnnounceRequest notification - which requests for all servers to send out ServerAnnounce notifications. Clients can then build a list of all servers available.

The App Sandbox allows distributed notifications but disallows any payload. See the discussion in .

I believe this is the fundamental problem, as the CFMessagePort name is part of the ServerAnnounce payload - it is how clients discover what CFMessagePort to connect to for each server.

And matches what I see empirically - if I add an App Group and change the naming convention of the CFMessagePort to match the App Group - I no longer see the "Permission Denied" error, however, because there is no payload, the client has no way of discovering the CFMessagePort name that my app (a server) is using.

Oh, one last thing: Are you concerned about sandboxing because you want to ship on the Mac App Store? Or just because it’s the right thing to do?

My app is already shipping on the Mac App Store, and Syphon support is one of the most requested features among VJ enthusiasts and professionals. Keeping it on the Mac App Store is a high priority, but it looks like the Sandbox restriction of no payload for distributed notifications is a big hurdle. If the App Store didn't require a sandbox, I would not be using the Sandbox at all.

Accepted Answer
My app is already shipping on the Mac App Store

Yeah, that makes things tricky. I don’t see any way to implement the IPC protocol as you’ve described it in a sandboxed app. Given that, I see two possible paths forward:

  • You could build some sort of adaptor that bridges between your app and this protocol, and distribute that directly using Developer ID signing.

  • You could engage with the Syphon community to rework or extend the protocol into something that’s compatible with the App Sandbox.

Both of these are tricky. The first has potential App Review implications. The second assumes that it’s possible to design such a protocol, and then you have to get other apps to update.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

You could engage with the Syphon community to rework or extend the protocol into something that’s compatible with the App Sandbox.

I wish, but not gonna happen. It is a very established protocol / framework that all of the big name programs already use (Processing, Max/MSP, TouchDesigner, Resolume, BlackMagic, etc).

The first idea seems a little too obtuse for the users. If I have to self distribute, I might as well self distribute the actual "Pro" version of the app.

The key piece that I was missing ended up being that payloads are not allowed in NSDistributedNotificationCenter. Bummer.

Thanks a bunch for your time and help!

How to use CFMessagePort in a Sandbox App when App Group naming convention is not possible?
 
 
Q