Lock icon not visible in .pkg installer

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.

Answered by DTS Engineer in 791991022
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"

Accepted Answer
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"

My apologies, I didn't notice that packagesbuild was a third-party tool, I took over the project from a different developer, so I'm not a 100% familiar with the tooling yet.

I had a look at the link you sent and managed to get it working by running the productbuild command on the .pkg file generated by packagesbuild.

productbuild --sign "Developer ID Installer: [...]" \
		--package "com.optimidoc.cloudclientsigned.pkg" \
		"com.optimidoc.cloudclient.distribution.pkg" 

I suspect that the problem was in the fact that packagesbuild generates a "component package" (similar to pkgbuild) rather than a "product archive" like productbuild does, but I haven't done any testing to verify it.

Thank you for pointing me in the right direction.

Lock icon not visible in .pkg installer
 
 
Q