I have a parent installer package, say, called Parent.unsigned.mpkg
that I would like to sign with OS X productsign
.
The file Parent.unsigned.mpkg
contains children packages called A.pkg
, B.pkg
and C.pkg
, which in turn install Clang-compiled command-line binaries and bash
wrapper scripts:
./Parent.unsigned.mpkg/Contents/Packages/A.pkg
./Parent.unsigned.mpkg/Contents/Packages/B.pkg
./Parent.unsigned.mpkg/Contents/Packages/C.pkg
I signed up for a Mac Developer account, which sets up (among other certificates) a Developer ID Installer certificate with the ID ABCD1234
(this ID is actually different and specific to my Apple ID.) I obtain this ID value using the security
tool:
$ security find-certificate -a -c "Developer ID Installer" | grep "alis"
"alis"<blob>="Developer ID Installer: Foo B. Baz (ABCD1234)"
I sign each of these children packages with this ID value, which appears to proceed without incident:
$ productsign --timestamp --sign ABCD1234 ./Parent.unsigned.mpkg/Contents/Packages/A.pkg ./Parent.unsigned.mpkg/Contents/Packages/A.signed.pkg
...
$ productsign --timestamp --sign ABCD1234 ./Parent.unsigned.mpkg/Contents/Packages/B.pkg ./Parent.unsigned.mpkg/Contents/Packages/B.signed.pkg
...
$ productsign --timestamp --sign ABCD1234 ./Parent.unsigned.mpkg/Contents/Packages/C.pkg ./Parent.unsigned.mpkg/Contents/Packages/C.signed.pkg
...
I then move these signed children packages back to their original filenames:
$ mv ./Parent.unsigned.mpkg/Contents/Packages/A.signed.pkg ./Parent.unsigned.mpkg/Contents/Packages/A.pkg
$ mv ./Parent.unsigned.mpkg/Contents/Packages/B.signed.pkg ./Parent.unsigned.mpkg/Contents/Packages/B.pkg
$ mv ./Parent.unsigned.mpkg/Contents/Packages/C.signed.pkg ./Parent.unsigned.mpkg/Contents/Packages/C.pkg
When I try to productsign
the parent package, I get the following warning messages:
$ productsign --timestamp --sign ABCD1234 ./Parent.unsigned.mpkg ./Parent.signed.mpkg
productsign: preparing "Parent.unsigned.mpkg" for signing ...
productsign: Using timestamp authority for signature
productsign: warning: component package "A.pkg" not found inside "Parent.unsigned.mpkg" and must be signed explicitly
productsign: warning: component package "B.pkg" not found inside "Parent.unsigned.mpkg" and must be signed explicitly
productsign: warning: component package "C.pkg" not found inside "Parent.unsigned.mpkg" and must be signed explicitly
productsign: Wrote signed product archive to ./Parent.signed.mpkg
When I try to verify that the installer is signed, I get a rejection message:
$ spctl -a -v --type install ./Parent.signed.mpkg
./Parent.signed.mpkg: rejected
I am using Apple's directions outlined here and here.
The unsigned installer works correctly as it is, but it requires bypassing OS X Gatekeeper. So the installer bundle and contents appear to be correct (or at least working correctly).
What steps or procedures am I missing that generate a digitally-signed installer that works with OS X Gatekeeper?
I used
Packages.app
to create the package project.Within
Packages.app
, I changed the project type fromBundle
toFlat
and rebuilt the Installer archive.I then proceeded with the
productsign
steps via command line as described above, except that I only need to sign the parentpkg
file to generate a working, signed Installer (I did not sign the children packages).Using
pkgutil --flatten
to try to flatten thempkg
bundle output on the command-line ended up corrupting the Installer — I had to change the project type fromBundle
toFlat
withinPackages.app
and rebuild the Installer within that application, and sign the flat Installer file outsidePackages.app
.