Summary
We have a .net 8 application that consists of 2 components, a GUI app and a launch daemon. The .pkg file for the GUI app is created by Visual Studio, and this .pkg is then bundled with the launch daemon into one installer using the packagesbuild utility.
The problem we're facing is that our customer's MDM system is refusing to install the app because of a missing lock icon in the installer, which makes it look as if the app was not signed even though it is (shown on the right in the image below).
Installer package contents
The .pkg file created by packagesbuild contains the GUI app .pkg file shown on the left in the image above, signing of this file is handled by the .net build process.
It also contains two third party .dylib files (one for intel, the other for arm), which are re-signed with the following command:
codesign --sign "Developer ID Application: [...]" \
--force --options runtime --no-strict \
"<file-path>"
The launch daemon is build with .net and then signed using this command:
codesign --sign "Developer ID Application: [...]" \
--force --options runtime --no-strict \
--entitlements "<entitlements-path>" \
"<file-path>"
I don't know if it's relevant, but there are also several .plist and .json files.
Final package signing
The .pkg file created by packagesbuild is signed using:
productsign --sign "Developer ID Installer: [...]" \
--cert "Developer ID Installer: [...]" \
"com.optimidoc.cloudclient.pkg" \
"com.optimidoc.cloudclientsigned.pkg"
After signing, the package is notarised with xcrun notarytool
.
Both the signing and notarisation finish without error, which I've validated by running pkgutil --check-signature "<file-path>"
Package "com.optimidoc.cloudclientsigned.pkg":
Status: signed by a developer certificate issued by Apple for distribution
Notarization: trusted by the Apple notary service
Signed with a trusted timestamp on: 2024-06-13 11:41:57 +0000
Certificate Chain:
1. Developer ID Installer: OptimiDoc s.r.o. (2YMBVCM8TM)
Expires: 2028-03-01 07:37:30 +0000
SHA256 Fingerprint:
02 E2 C1 A0 06 E1 C1 A2 FF 70 BD CD A5 47 43 B2 DB CF 62 BB 6D D4
90 69 3E 7C C8 A7 29 73 7D 69
------------------------------------------------------------------------
2. Developer ID Certification Authority
Expires: 2031-09-17 00:00:00 +0000
SHA256 Fingerprint:
F1 6C D3 C5 4C 7F 83 CE A4 BF 1A 3E 6A 08 19 C8 AA A8 E4 A1 52 8F
D1 44 71 5F 35 06 43 D2 DF 3A
------------------------------------------------------------------------
3. Apple Root CA
Expires: 2035-02-09 21:40:36 +0000
SHA256 Fingerprint:
B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E DA 6B CA ED 7E 2C
68 C5 BE 91 B5 A1 10 01 F0 24
What I've tried
I played around with the signing process for a few days but I was unable to figure out where the installer UI gets the certificate information from.
I've tried limiting the files included in the final .pkg file. First I tried only including the GUI app .pkg with a known good signature. I also tried only including the launch daemon executables. All to no avail.
In regard to the packagesbuild utility, I noticed the --identity
option, but at the moment I'm stuck with an "unknown error" message:
The command is:
packagesbuild "com.optimidoc.cloudclient.pkgproj" -v \
--identity "Developer ID Installer: [...]" \
--keychain "/Library/Keychains/System.keychain"
And the output I get is:
Building Project (11:56:49) at path: [...]
------------------------------------------------------------------------------
Build Folder (done)
Package "com.optimidoc.cloudclient"
Payload
Assemble file hierarchy (done)
Split forks (done)
Create bill of material (done)
Create pax archive (done)
Scripts
Assemble file hierarchy (done)
Split forks (done)
Create pax archive (done)
PackageInfo (done)
Create xar archive
==============================================================================
ERROR:
Description:
Unknow Error
==============================================================================
Build Failed
I think the --identity option is the way forward, but I don't know how to debug the "unknown error" message. I've sunk a few days into this problem already, so any help would be greatly appreciated. I'll update the post if I have any news.
using the packagesbuild utility.
I’m not familiar with that. Is that a third-party tool?
My general advice in this front is that you create a small test program with Apple tools and then see if that works. If it does, that has two benefits:
-
It confirms that your signing and notarisation is working correctly.
-
It gives you a working example that you can use to run further tests.
For the simplest possible command to build a signed installer package for distribution, see Packaging Mac software for distribution.
Oh, one more thing. The installer doesn’t look at the contents of your package to decide whether to show the lock or not. Rather, it looks at just the package itself. So, this problem is tied to your package creation, not your code.
In contrast, the notary service does look inside your package, so the fact that it passes notarisation suggests that the contents of the package are fine.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"