Unable to communicate with Network Extension using IPC

I have a network extension (AppProxyProvider) hosted inside a Mac OS app. Both are signed with the same Developer ID. I am able to programatically install and start the extension from the hosting app:

session.startTunnel()

The proxy provider is successfully started and works as expected.

Unfortunately I am not able to communicate with the extension from the app:

session.sendProviderMessage(data)

Doesn't return any error but the handleAppMessage method is never called. Also I see the following error in the system log:

nesessionmanager: [com.apple.networkextension:] NESMTransparentProxySession[Primary Tunnel:My Transparent Proxy:60F50D75-194D-4FB6-A9D9-7639A561DF5E:(null)]: process 43158 is not entitled to establish IPC with plugins of type xxxxx

where xxxxx is the bundle id of my hosting app.

Is there some entitlement that I am missing? Could this somehow be related with the com.apple.security.application-groups entitlement and the TeamID prefix that gets prepended?

I am testing this on Mac OS Ventura 13.2.1

Answered by DTS Engineer in 755747022

where xxxxx is the bundle id of my hosting app.

In extension terminology, we use container app. The host app is the app that loads the plug-in, which in this case in the system itself.

or I should use XPC instead?

Most folks doing system extensions do in fact use XPC. It’s a much more capable IPC. AFAIK provider messaging should work for a system extension, but I’ve never actually tested it myself.

Also I see the following error in the system log:

That messages suggests that either your app or your sysex has an entitlement issue. Make sure that:

  • Both are signed with a provisioning profile, and so have the com.apple.application-identifier entitlement.

  • The sysex’s value is a direct child of the app’s.

  • Neither is signed with the app group entitlement [1].

  • Both are signed with the NE entitlement (com.apple.developer.networking.networkextension) with the same value (app-proxy-provider in your case).

Don’t check this stuff by looking in your .entitlements file; rather, check the built binary using:

% codesign -d --entitlements - /path/to/your.app
% codesign -d --entitlements - /path/to/your.app/path/to/your.systemextension

Share and Enjoy

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

[1] App groups generally aren’t helpful with a sysex because your app and sysex are running as different users. And app groups can cause weird issues, as discussed in App Groups: macOS vs iOS: Fight!.

I have a network extension (AppProxyProvider) hosted inside a Mac OS app

Just out of curiosity, what type of AppProxyProvider are you using? Is it a AppProxyProvider System Extension or is it an App Extension?

Just out of curiosity, what type of AppProxyProvider are you using? Is it a AppProxyProvider System Extension or is it an App Extension?

@meaton, it is a system extension.

It is also worth mentioning that the IPC works while debugging in XCode (using XCode managed Profile and Apple Development signing certificate for both the app and the sysext). So I guess there might be some issue with my Developer ID signing profile and/or entitlements

My current workaround is to stop and start the extension again from the container app since the start method allows me to pass some options. This is quite ugly and would really like to find out why sendProviderMessage is failing to communicate with my sysext. Is this a supported scenario (container app sendProviderMessage -> Mac OS system extension handleAppMessage) or I should use XPC instead?

Accepted Answer

where xxxxx is the bundle id of my hosting app.

In extension terminology, we use container app. The host app is the app that loads the plug-in, which in this case in the system itself.

or I should use XPC instead?

Most folks doing system extensions do in fact use XPC. It’s a much more capable IPC. AFAIK provider messaging should work for a system extension, but I’ve never actually tested it myself.

Also I see the following error in the system log:

That messages suggests that either your app or your sysex has an entitlement issue. Make sure that:

  • Both are signed with a provisioning profile, and so have the com.apple.application-identifier entitlement.

  • The sysex’s value is a direct child of the app’s.

  • Neither is signed with the app group entitlement [1].

  • Both are signed with the NE entitlement (com.apple.developer.networking.networkextension) with the same value (app-proxy-provider in your case).

Don’t check this stuff by looking in your .entitlements file; rather, check the built binary using:

% codesign -d --entitlements - /path/to/your.app
% codesign -d --entitlements - /path/to/your.app/path/to/your.systemextension

Share and Enjoy

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

[1] App groups generally aren’t helpful with a sysex because your app and sysex are running as different users. And app groups can cause weird issues, as discussed in App Groups: macOS vs iOS: Fight!.

I think I have found the problem. When I was building my application in Release mode I was using manual signing with codesign and the following entitlements were not added to my app:

<key>com.apple.application-identifier</key>
<string>CXXXXXXXX.com.myorg.myapp</string>

<key>com.apple.developer.team-identifier</key>
<string>CXXXXXXXX</string>

After manually adding them to the entitlements file, the IPC started working as expected.

Unable to communicate with Network Extension using IPC
 
 
Q