macOS: pkg signing full chain workflow

Alexey Semenyuk alexey.semenyuk at oracle.com
Mon Feb 23 16:38:14 UTC 2026


Hi Florent,

jpackage doesn't build the application jar. Likewise, it doesn't 
notarize and staple the package. These limitations leave steps 1, 2, 10, 
and 11 out of scope. The remaining steps are handled by jpackage, and 
each can be customized.
There are three CLI options to control signing certificates: 
--mac-signing-key-user-name, --mac-app-image-sign-identity, and 
--mac-installer-sign-identity.
--mac-signing-key-user-name option allows specifying a portion of the 
names of certificates for signing the application bundle and .pkg 
installer. jpackage will use the value of this option to lookup for 
certificates.
E.g., say you have "Developer ID Application: Acme Software LLC 
(ABCD1234)" and "Developer ID Installer: Acme Software LLC (ABCD1234)" 
certificates. You can instruct jpackage to use them in steps 3-9 by 
adding "--mac-signing-key-user-name 'Acme Software LLC (ABCD1234)'" to 
the command line.
If you want to explicitly specify certificates, you may use 
--mac-app-image-sign-identity and --mac-installer-sign-identity options.
The value of the --mac-app-image-sign-identity option should be the full 
name of the certificate for signing application bundle.
The value of the --mac-installer-sign-identity option should be the full 
name of the certificate for signing .pkg installer.

Additionally, you can specify the name of the keychain with the 
certificates with the --mac-signing-keychain option and the entitlements 
file with --mac-entitlements option.

All these options are valid only when used with "--mac-sign" option.

- Alexey

On 2/23/2026 5:53 AM, Florent MARTIN wrote:
>
> Hello,
>
> For an application, I need to create a pkg for macOS of a Java 
> application, but jpackage does not provide support for all the steps 
> required. As a reminder, here is the full workflow needed to create a 
> valid pkg that passes Gatekeeper on macOS, which requires three 
> different certificates:
>
>   * A standard signing certificate
>   * An Apple Developer ID Application certificate
>   * An Apple Developer ID Installer certificate
>
> The full workflow is:
>
>  1. Signing the native libraries inside the JAR (requires a Developer
>     ID Application certificate)
>       * Basically, this involves extracting the JAR, signing all
>         .jnilib and .dylib files, and rebuilding the JAR.
>  2. Signing the JAR itself (requires a standard certificate)
>       * Using jarsigner to pass the JVM security check.
>  3. Generating an application image (.app)
>  4. Signing the native libraries included in the image (requires a
>     Developer ID Application certificate)
>  5. Signing the main executable of the image (requires a Developer ID
>     Application certificate)
>  6. Signing the main bundle of the image (requires a Developer ID
>     Application certificate)
>  7. (Optional) Adding an entitlements.plist file to allow JNI usage
>       * Needed if using restricted features such as JNI.
>  8. Creating the installer package (.pkg)
>  9. Signing the installer package (requires a Developer ID Installer
>     certificate)
> 10. Notarizing the package (submission to Apple for verification)
> 11. Stapling the package (embedding the notarization directly into the
>     package)
>
> If we skip steps 1 and 2 for preparing the JAR (it would be better if 
> jpackage could handle this automatically), as well as steps 10 and 11, 
> then for steps 3 to 9 we need to use two different certificates, but 
> jpackage provides only a single `--mac-sign` parameter, which does not 
> support multiple certificates and would ideally be split into separate 
> parameters for the application certificate and the installer 
> certificate; as a result, when creating a pkg with jpackage, the App 
> Image inside remains unsigned, which causes Gatekeeper to block the 
> application.
>
> Best regards,
>
> *Florent MARTIN*
>
> Développeur
>
> Cegid Relations Bancaires
>
> +33 (0)2 99 55 33 22
>
> flmartin at cegid.com <mailto:flmartin at cegid.com>
>
> 	
>
> 	
>
> Facebook <https://www.facebook.com/CegidGroup/>Twitter 
> <https://twitter.com/CegidGroup>LinkedIn 
> <https://fr.linkedin.com/company/cegid>
> *cegid.com* <https://www.cegid.com/>**
>
> 	
>
> Cegid <http://www.cegid.com/>
>
>
>
> Cegid est susceptible d’effectuer un traitement sur vos données 
> personnelles à des fins de gestion de notre relation commerciale. Pour 
> plus d’information, consultez https://www.cegid.com/fr/privacy-policy
> Ce message et les pièces jointes sont confidentiels et établis à 
> l'attention exclusive de ses destinataires. Toute utilisation ou 
> diffusion, même partielle, non autorisée est interdite. Tout message 
> électronique est susceptible d'altération; Cegid décline donc toute 
> responsabilité au titre de ce message. Si vous n'êtes pas le 
> destinataire de ce message, merci de le détruire et d'avertir 
> l'expéditeur.
>
> Cegid may process your personal data for the purpose of our business 
> relationship management. For more information, please visit our 
> website https://www.cegid.com/en/privacy-policy
> This message and any attachments are confidential and intended solely 
> for the addressees. Any unauthorized use or disclosure, either whole 
> or partial is prohibited. E-mails are susceptible to alteration; Cegid 
> shall therefore not be liable for the content of this message. If you 
> are not the intended recipient of this message, please delete it and 
> notify the sender. 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20260223/a0bbfb8e/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 1048 bytes
Desc: not available
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20260223/a0bbfb8e/image001-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 1264 bytes
Desc: not available
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20260223/a0bbfb8e/image002-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image003.png
Type: image/png
Size: 1388 bytes
Desc: not available
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20260223/a0bbfb8e/image003-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image004.png
Type: image/png
Size: 8492 bytes
Desc: not available
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20260223/a0bbfb8e/image004-0001.png>


More information about the core-libs-dev mailing list