Signing the wrapper package with a Developer ID Installer certificate is mandatory. Notarization is a separate Apple verification step and is strongly recommended alongside
signing.
Before you begin
Obtain both of the following before you begin.
- A Developer ID Installer certificate. If the certificate is not already installed, generate a certificate signing request (CSR) in Keychain Access, using . Then, in the Apple Developer portal under , create a Developer ID Installer certificate from that CSR, download the resulting .cer file, and double-click it to
install it into the Keychain of the build macOS endpoint.
Note: On an organization account, only the Account
Holder, or an Admin with the Certificates, Identifiers & Profiles - Developer ID access role, can create Developer ID certificates.
- An app-specific password for notarization. This is not your ordinary Apple ID password, which the notarization service rejects, particularly when two-factor
authentication is enabled. Generate an app-specific password at appleid.apple.com, under . Apple displays the generated password only once, so copy it before you close the
page.
- Your Apple Developer Team ID. Sign in at developer.apple.com/account and open Membership Details. The Team ID is the 10-character alphanumeric string shown there, and
replaces
TEAMID everywhere it appears below.
Important: Microsoft's official documentation requires that any .pkg uploaded as a macOS LOB app be signed with a Developer ID Installer certificate
obtained from an Apple Developer account. If the package is not signed, Intune accepts the upload, but the install silently fails on every target macOS endpoint when pushed through the MDM
channel, even though the same package may install successfully when run manually in Terminal. Notarization ensures that Gatekeeper does not flag the installer as being from an
unidentified developer.
Signing embeds a cryptographic signature into the package, generated using a certificate tied to a specific Developer ID or Team, and to a bundle identifier registered under that
developer account. This proves to macOS that the package genuinely comes from your organization and has not been tampered with since it was built. Notarization goes a step further:
Apple's servers scan the signed package for known malicious content and issue a ticket confirming that it passed the check. Gatekeeper checks for both of these before allowing many
types of installers to run without warnings.
The bundle identifier used for signing must be the same reverse-DNS identifier assigned to the wrapper package when it was built (for example,
com.forcepoint.websenseendpoint.wrapper). The identifier is recorded in the package receipt on the target macOS endpoint, where it can be confirmed with pkgutil
--pkgs. Apple's notarization service tracks each submission by the submission UUID that notarytool returns, not by the bundle identifier.
Steps
-
On the build macOS endpoint, confirm that the Developer ID Installer certificate is present in Keychain:
security find-identity -v -p basic
Look for an entry that reads Developer ID Installer: <Your Organization Name> (<TEAMID>) in the output. This exact name string is used in
the signing command. If no such entry is listed, the certificate is not installed on this endpoint; obtain it as described in the prerequisites before continuing.
-
Sign the package:
productsign --sign "Developer ID Installer: Your Organization (TEAMID)" \
WebsenseEndpointInstaller.pkg \
WebsenseEndpointInstaller-signed.pkg
-
Verify that the signature was applied correctly:
pkgutil --check-signature WebsenseEndpointInstaller-signed.pkg
The output confirms that the package is signed by a developer certificate issued by Apple for distribution, and lists Developer ID Installer in
the certificate chain. If it reports Status: no signature, the signing step did not apply correctly and must be repeated before continuing.
-
Store your notarization credentials in the Keychain, so that the app-specific password is not passed on the command line:
xcrun notarytool store-credentials "Notarytool" \
--apple-id "your-apple-id@example.com" \
--team-id "TEAMID"
The command prompts for the app-specific password and saves it to the Keychain under the profile name. The notarization commands that follow reference the profile rather than
the password itself. You only need to do this once per build endpoint.
Note: Use the profile name Notarytool exactly as shown. The signing and notarization helper
scripts reference the profile by that name.
Important: Do not pass --password on the command line. The value is written to your shell history and is briefly visible to other local processes
through ps. Where a stored profile cannot be used, such as in an automated build, supply the password through an environment variable instead, using
--password "@env:NOTARY_PASSWORD".
-
Confirm that the stored profile authenticates:
xcrun notarytool history --keychain-profile "Notarytool"
An empty list is expected on a new profile. An authentication error means that the Apple ID, Team ID, or app-specific password was not accepted; repeat the previous step
before continuing.
-
Submit the signed package to Apple's notarization service:
xcrun notarytool submit WebsenseEndpointInstaller-signed.pkg \
--keychain-profile "Notarytool" \
--wait
The --wait flag causes the command to stay running and report back once Apple's automated review completes. This typically takes a few minutes.
A result of
status: Accepted confirms that notarization succeeded. If the result is
Invalid, request the detailed
log for troubleshooting:
xcrun notarytool log <submission-id> --keychain-profile "Notarytool"
-
Staple the notarization ticket to the package so that it can be verified offline, without contacting Apple's servers, at install time:
xcrun stapler staple WebsenseEndpointInstaller-signed.pkg
Important: Do not alter the package in any way after stapling. Re-compressing it, unpacking and repacking it, or re-signing it strips or invalidates the stapled
ticket, and the package must then be signed, notarized, and stapled again. Upload the stapled file to Intune exactly as this step produces it.
-
Confirm that both signing and notarization are correctly in place:
spctl -a -vvv -t install WebsenseEndpointInstaller-signed.pkg
A successful result reads accepted and lists the source as Notarized Developer ID. A result
of rejected with source=Unnotarized Developer ID means the package is signed but was never successfully
notarized.
-
Confirm that the notarization ticket is stapled to the package:
xcrun stapler validate WebsenseEndpointInstaller-signed.pkg
A successful result reads
The validate action worked!A stapled ticket travels inside the file, so Gatekeeper can approve the package
without contacting Apple. Without it, the target endpoint must reach Apple's notarization servers at the moment of install, which an MDM-triggered install cannot be relied
upon to do. This check therefore matters more for Intune deployments than for an interactive install.
Next steps
Note: WebsenseEndpointInstaller-signed.pkg, after stapling, is the file to upload to Intune. Do not upload the original unsigned
WebsenseEndpointInstaller.pkg.
Important: Intune neither signs nor notarizes the packages that it receives. It distributes the package exactly as uploaded. A package that was never signed, or whose ticket
was stripped after stapling, is still accepted at upload and then fails silently on every target macOS endpoint. The local spctl check above is the last point at
which this is detectable.
Note: Repeat this entire procedure for every new build. Signatures and stapled notarization tickets do not carry over
from a previous build, even one that is otherwise identical.