Home > Back-end >  Extensions not opening if they are signed using the command line tools
Extensions not opening if they are signed using the command line tools

Time:11-01

We have recently discovered an issue where extensions in an app bundle would not open if they are signed (using codesign, in our case). We are assuming that this is because they can either not be run by the main app (because of some signing/security issue) or that the system immediately kills them because they are incorrectly signed.

The setup

  1. Simply create a main app containing any app extension (we have tried FinderSync and Share)
  2. Archive and export the app using the xcodebuild command (though exporting it through Xcode works aswell)
  3. Sign the app container (.app) and the extension (.appex file in Contents/PlugIns).
  4. Open the app
  5. The Extension won't be visible in the Preferences and is not running

The problem

If we do not sign the app extension, the main app and app extension start as expected (this not an option though, because notarization will fail when the app extension is not signed). If we sign the app extension, the app extension will not start (when running the main app). We assume that this is because macOSs Gatekeeper immediately kills them when started. But we are not sure why.

Demo Project

You can find a very simple demo project in the Github Repository linked below. This demo project only contains an almost empty main app, a completely default App Extension (everything is left as when generated, except the myFolderURL which was changed to / for testing purposes).

The demo project also contains two scripts, one which builds app and signs it completely (with app extension) and one which builds the app and signs everything but the App Extension. Both scripts export a .app file, and a zip file.

Make sure to insert the name of your Developer ID Application Certificate into the script (simply replace the XXXXXXX with the name of your certificate)

To reproduce our issue:

  1. Run the unsigned app and open the preferences with the button to confirm that the app extension have been added.
  2. delete the app (to make sure the app extension is not still in the preferences when testing the signed app)
  3. Open the app with the signed extension and you'll see that upon opening the app and viewing the preferences that the app extension is not present in the list (and therefore not open). This can be tested using the Activity Monitor or 'top' command as well.

Link to the Demo Project: Github Repository

Conclusion

To summarise: When signing an app extension (Finder Sync in the Demo), the extension does not open/gets killed when the extension is signed. If the extension is not signed everything works as intended. As said, we believe that either signing, notarising, or the gatekeeper might be the cause of this issue, probably this is some issue with our build/sign automation (the demo contains the scripts with our automation code). Can that be the case or are extensions handled differently and we are missing a step?

CodePudding user response:

For anyone else experiencing this issue, we finally figured it out:

In the end, this is the command we were using to sign our extensions with (incorrect command):

codesign -s "Developer ID Application: XXXXXXXXX (XXXXXXX)" -f --timestamp -o runtime "OurApp.app/Contents/PlugIns/OurExtension.app"

After some digging in the Console, we found that the extensions were being closed by the gatekeeper with the following message:

[/Applications/Extension_With_Signing_Demo.app/Contents/PlugIns/findersynctest.appex]: plug-ins must be sandboxed

After discovering this message, the cause of the error was pretty clear for us: Because we hadn't deemed it necessary to actually pass entitlements while signing the extension (because we thought that they didn't require any) and we didn't know that extensions require sandbox to run.

To solve the issue, all we did was add an entitlements plist file containing some of the basic entitlements:

<?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-only</key>
    <true/>
</dict>
</plist>

and included them in our command

codesign -s "Developer ID Application: XXXXXXXXX (XXXXXXX)" -f --timestamp -o runtime --entitlements EntitlementsFile.entitlements "OurApp.app/Contents/PlugIns/OurExtension.app"

After that, the extensions started as intended.

Summary

The solution to our problem was the fact that we didn't pass any entitlements when signing the extensions, even though extensions require the sandbox entitlement.

A very helpful resource on how to add entitlements when signing an app or app extension (and code signing in general): Creating Distribution-Signed Code for Mac

  • Related