Network Extension - Cannot run debug build on other Mac devices (Catalina)

Hello.

We have a VPN app distributed via App Store and it uses Network Extensions (tunnel provider). App Store app works fine.

We have a list of Mac devices added in our profile for testing. Their hardware UUIDs are in the developer profile. When I build the app and run it on one of these Macs, Network Extension refuses to start. The GUI app itself opens fine but when it's time to start VPN, the extension won't start. I get the following error messages :

Signature check failed: code failed to satisfy specified code requirement(s)

NEVPNTunnelPlugin(com.XYZ.XYZ[inactive]): Validation of the extension failed

This happens on Catalina and Big Sur but runs fine on Mojave even though we see the same messages on Console. Do we have to notarise our debug builds also, to run debug builds on test devices? Or do we have to provide another entitlement?

Even if it was an issue with notarisation, I got a popup saying "Cannot check for malicious softwares etc etc" and I went to security preferences and explicitly allowed the app.
Also, it runs fine on the machine it was built on. It just won't run on other test machines.

Replies

Do we have to notarise our debug builds also, to run debug builds on test devices?

Yes. To test and distribute builds for other test machines you will need to sign with a Developer ID identity and Notarize your build.

Also, it runs fine on the machine it was built on. It just won't run on other test
machines.

This makes sense as you are signing with your Development Signing Identity that is present in your Keychain and you are not distributing a container to your device that requires Gatekeeper approval.

Even if it was an issue with notarisation, I got a popup saying "Cannot check for malicious softwares etc etc" and I went to security preferences and explicitly allowed the app.

This could mean that Gatekeeper could not recognize the Notarization ticket stapled to the app or the distribution container. For more on nailing down your workflow here, checkout these two posts that Quinn wrote:

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Hello Matt,
Thanks for the reply.

We do have "Mac Development" certificate. If we login to developer portal and select "Certificates, Identifiers & Profiles
", we generated "Mac Development" certificate there for development. Note : This is not "Developer ID Installer" or "Developer ID Application"

There's also "Mac App Distribution" certificates that are used for App Store distribution(not relevant here because App Store build works fine)

Then, in the same menu, we have "Devices" menu where we add the UUID of the test machines. We can add up to 100 devices. Then we create a "Profile" for the main app and one for NetworkExtension which are added to our Xcode. The UUIDs of these 100 devices go into the "embedded.provisionprofile" of the app.

If I open my app cd MyApp.app/Contents/embedded.provisionprofile, I can see all the UUIDs listed under ProvisionedDevices.
Does this not suffice to run our app on these 100 test machines?
If we have to notarise, why is there a facility to add 100 test devices?

Also, in any case, I did notarise and it still failed with "message": "The binary is not signed with a valid Developer ID certificate.",

codesign shows the following :

Signature size=4832
Authority=Apple Development: NAME (123ABCDE4F)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=28-Jan-2021 at 6:19:07 PM

Does this mean I have to sign it with a certificate that's exclusively of the type "Developer ID Application" ?

Is there no way to distribute with the Apple Development certificates we already have?

Note 2 : We're not trying to run the app on any machine, just one of the 100 test machines we have added to our profile.

Does this not suffice to run our app on these 100 test machines? If we have to notarise,
why is there a facility to add 100 test devices?

Notarization is for distributing builds to users or testers that may not be registered on your Development team or do not have a device listed in your Devices list. If you have a macOS Development profile then you probably have a set of Devices listed on it. This would allow you to pull down your project on one of these devices, build and run using your Development Profile and Certificate, and develop and test from the listed device. This assumes that you are building, testing, and debugging from Xcode though.

Also, in any case, I did notarise and it still failed with "message": "The binary is not signed with a valid Developer ID certificate.",

Does this mean I have to sign it with a certificate that's exclusively of the type "Developer ID Application" ?

For Notarization, yes. You will need to sign with a Developer ID certificate.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Hi Matt.

I see the initial steps (manually allowing app to run), but once it's approved we can see that the binary is loaded
  • The class initializer for PacketTunnelProvider runs.

  • There's log output from the class initializer, so we know that the VPN extension has been loaded successfully

  • The entry point (startTunnelWithOptions:completionHandler:) is never called

  • The VPN extension exits

  • There's no crash log

I'd think that a signing problem would result in the binary not being loaded, right?




@kjbrock

For your PacketTunnelProvider issue, it's hard to determine if it's code related, configuration related, or code signing related. There's no way to tell based on your description. It may be best to create a new post with the specifics of your question to get the full picture. Having said that, the first place I would look to debug what is happening in your provider is just general logs that are emitted from the Console.app. This usually can get you pointed in the right direction.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Hello @Matt.

I finally got this working :) .
The solution was to delete all the VPN profiles from System Preferences -> Network and create new ones with the debug build app.

So, here's all the steps :
  1. Our regular way of distribution is through macOS App Store

  2. For building code, we have Mac Development and/or Apple Development profiles (not using Developer ID profiles here). We have added our development devices and test devices to the list of devices (max limit of 100)

  3. On the test devices, If we download the code, build and run through Xcode, it'll run fine. But if we built on one machine, we cannot run it on another machine (even if we allow the app to run from "system preferences->Security & privacy -> Allow anyway"). The main GUI app works well. The extension starts but quits before it calls "startTunnelWithOptions".

  4. After a bit of experimenting, we figured out that we had to delete the old VPN profiles on the test devices. So, build on one machine. Copy the app to another (test)machine-> Delete all VPN profiles on that test machine -> Open the app and create new VPN profiles and extension successfully loads and VPN runs! No developer ID certificate required. No notarisation required because this is not meant for general distribution but only to a list of 100 test devices, usually internally and those users can manually allow the app to run.

I finally got this working :) .

That's great news!


I think the key piece here was:

we figured out that we had to delete the old VPN profiles on the test devices.
No notarisation required because this is not meant for general distribution but only to a list of 100 test devices

And this works because I suspect that the device you are running the build on is included in the development provisioning profile that the app is built with.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com