Guide to Sign, Notarize and Staple Your Go App for outside Mac App Store distribution

Guide to Sign, Notarize and Staple Your Go App for outside Mac App Store distribution

Rubi

Jun 24, 2024

This post is written based on our experience on signing and notarizing Mac software, You could try the result by downloading our latest wails.io based Mac software

SUPPORT INDIE PRODUCT - Our Beta Pricing is out! Checkout now lokal.so/pricing

If you're distributing your Mac app outside the App Store, you'll need to sign and notarize it to ensure it runs smoothly on users' machines. This guide will walk you through the process.

Understanding Signing and Notarizing

Before we dive into the process, it's crucial to understand what signing and notarizing are and why they're important for your Mac app.

What is Code Signing?

Code signing is a security technology that uses a cryptographic signature to verify the authenticity of your app. It proves that the app comes from a known developer (you) and hasn't been tampered with since it was signed.

What is Notarization?

Notarization is an automated process where Apple checks your app for malicious content and code-signing issues. It's an additional layer of security introduced by Apple in macOS Catalina (10.15) and later.

Why Sign and Notarize?

If you don't sign and notarize your Mac app:

  1. Users will see Gatekeeper warnings when trying to open your app.

  2. Your app may be seen as less trustworthy.

  3. On macOS Catalina and later, your app will be blocked by default.

  4. You may lose access to certain macOS features and APIs.

  5. Distribution becomes more difficult as platforms may flag your app as potentially dangerous.

  6. There's no protection against tampering of your app.

By signing and notarizing, you provide a smoother, more trustworthy experience for your users and comply with Apple's security requirements.

Prerequisites

  • An Active Apple Developer account (Copy the Apple Team ID)

  • Xcode installed on your Mac

  • Your app (ex: Lokal.app or Mac App Package) ready for distribution

  • Bundle ID, we will guide this later

  • Developer ID Application and Developer ID Installer, we will guide this later

  • App Specific Password, we will guide this later

Creating App Bundle ID:

  1. Go to Certificates, Identifiers & Profiles

  2. Click on Identifiers on the left sidebar

  3. Click New Identifier Icon (+)

  4. Select for App IDs, Continue

  5. Select for App Type, Continue

  6. Write your Description, Your Bundle ID and check for necessary capabilities

Done, my Bundle ID is so.lokal.app

Creating "Developer ID Application" and "Developer ID Installer" Certificate

  1. Go to Certificates, Identifiers & Profiles

  2. Click on Certificates on the left sidebar

  3. Click New Certificate Icon (+)

  4. Scroll to middle of the page and select "Developer ID Application" or "Developer ID Installer", Continue

  5. Generate Developer ID Certificate

On this part, you need to have a certificate signing request, this is act like Private key while the generated certificate are the Public Key

Remember to backup your certificate signing request as you will not be able to sign an app without the same certificate signing request

If you lose your certificate signing request file, you need to generate a new CSR and create a new Developer ID Certificate (just happened to me yesterday because I had to downgrade from Sequoia to Sonoma)

  1. Download The Certificate

  2. Click two times on the cert file to Install it on Key Chain


If your certificate is not valid, you may need to click on it multiple times and change the Trust to "Always Trust"

Creating App-Specific Password

Notary tool requires you to log-in using your Apple account, the App-Specific Password are required to authorize you as owner of the account

  1. Visit Manage Your Apple ID, you may need to login

  2. Click on Sign-In and Security on the left sidebar

  3. Click on App-Specific Passwords

  1. Click + Icon, then you may need to enter the Label and re-login into your apple account.


After your had all the prerequisites, we continue to sign and notarize our app

Sign-in your Lokal.app

For more convenient way to sign your app, you may need to export the Name of the certificate on environment variable

export APP_CERTIFICATE="Developer ID Application: Rubi Jihantoro (XXXXXXXXXX)"
export PKG_CERTIFICATE="Developer ID Installer: Rubi Jihantoro (XXXXXXXXXX)"

Sign-in your .App package

codesign -s "$APP_CERTIFICATE" -f -v --timestamp --options runtime Lokal.app

During this time there is will be a pop-up for password authorization, this is normal.

Generate Installer .pkg and Sign the .pkg

productbuild --sign "$PKG_CERTIFICATE" --component Lokal.app /Applications Lokal-Installer.pkg

During this time there is will be a pop-up for password authorization, this is normal.

Notarize the generated .pkg file

xcrun notarytool submit ./Lokal-Installer.pkg --wait --apple-id "your@apple.email.com" --team-id YOUR_TEAM_ID --password "xxxx-xxxx-xxxx-xxxx"

IMPORTANT, if this is your first-time ever notarizing a file, Your notarization progress may be stuck, but DON'T PANIC, cancel the notarization process instead (by pressing control^+C), on my case, I just leave it for two days, then It's just working fine, in fact, someone even said run your notarize when its daytime on California.

Staple the notarized .pkg file

while this is optional, here the reason you might want to stable your pkg file:

  1. Offline Verification: Stapling allows macOS to verify that your app has been notarized even if the user's device is offline.

  2. Improved User Experience: Without stapling, macOS would need to check with Apple's servers every time the app is launched, which could cause delays.

  3. Gatekeeper Approval: A stapled ticket ensures that Gatekeeper immediately recognizes your app as notarized, allowing it to run without warnings.

> xcrun stapler staple Lokal-Installer.pkg
The staple and validate action worked


Please reach me on X if some of the tutorial are not working or need to be updated.

This post is written based on our experience on signing and notarizing Mac software, You could try the result by downloading our latest wails.io based Mac software

SUPPORT INDIE PRODUCT - Our Beta Pricing is out! Checkout now lokal.so/pricing

If you're distributing your Mac app outside the App Store, you'll need to sign and notarize it to ensure it runs smoothly on users' machines. This guide will walk you through the process.

Understanding Signing and Notarizing

Before we dive into the process, it's crucial to understand what signing and notarizing are and why they're important for your Mac app.

What is Code Signing?

Code signing is a security technology that uses a cryptographic signature to verify the authenticity of your app. It proves that the app comes from a known developer (you) and hasn't been tampered with since it was signed.

What is Notarization?

Notarization is an automated process where Apple checks your app for malicious content and code-signing issues. It's an additional layer of security introduced by Apple in macOS Catalina (10.15) and later.

Why Sign and Notarize?

If you don't sign and notarize your Mac app:

  1. Users will see Gatekeeper warnings when trying to open your app.

  2. Your app may be seen as less trustworthy.

  3. On macOS Catalina and later, your app will be blocked by default.

  4. You may lose access to certain macOS features and APIs.

  5. Distribution becomes more difficult as platforms may flag your app as potentially dangerous.

  6. There's no protection against tampering of your app.

By signing and notarizing, you provide a smoother, more trustworthy experience for your users and comply with Apple's security requirements.

Prerequisites

  • An Active Apple Developer account (Copy the Apple Team ID)

  • Xcode installed on your Mac

  • Your app (ex: Lokal.app or Mac App Package) ready for distribution

  • Bundle ID, we will guide this later

  • Developer ID Application and Developer ID Installer, we will guide this later

  • App Specific Password, we will guide this later

Creating App Bundle ID:

  1. Go to Certificates, Identifiers & Profiles

  2. Click on Identifiers on the left sidebar

  3. Click New Identifier Icon (+)

  4. Select for App IDs, Continue

  5. Select for App Type, Continue

  6. Write your Description, Your Bundle ID and check for necessary capabilities

Done, my Bundle ID is so.lokal.app

Creating "Developer ID Application" and "Developer ID Installer" Certificate

  1. Go to Certificates, Identifiers & Profiles

  2. Click on Certificates on the left sidebar

  3. Click New Certificate Icon (+)

  4. Scroll to middle of the page and select "Developer ID Application" or "Developer ID Installer", Continue

  5. Generate Developer ID Certificate

On this part, you need to have a certificate signing request, this is act like Private key while the generated certificate are the Public Key

Remember to backup your certificate signing request as you will not be able to sign an app without the same certificate signing request

If you lose your certificate signing request file, you need to generate a new CSR and create a new Developer ID Certificate (just happened to me yesterday because I had to downgrade from Sequoia to Sonoma)

  1. Download The Certificate

  2. Click two times on the cert file to Install it on Key Chain


If your certificate is not valid, you may need to click on it multiple times and change the Trust to "Always Trust"

Creating App-Specific Password

Notary tool requires you to log-in using your Apple account, the App-Specific Password are required to authorize you as owner of the account

  1. Visit Manage Your Apple ID, you may need to login

  2. Click on Sign-In and Security on the left sidebar

  3. Click on App-Specific Passwords

  1. Click + Icon, then you may need to enter the Label and re-login into your apple account.


After your had all the prerequisites, we continue to sign and notarize our app

Sign-in your Lokal.app

For more convenient way to sign your app, you may need to export the Name of the certificate on environment variable

export APP_CERTIFICATE="Developer ID Application: Rubi Jihantoro (XXXXXXXXXX)"
export PKG_CERTIFICATE="Developer ID Installer: Rubi Jihantoro (XXXXXXXXXX)"

Sign-in your .App package

codesign -s "$APP_CERTIFICATE" -f -v --timestamp --options runtime Lokal.app

During this time there is will be a pop-up for password authorization, this is normal.

Generate Installer .pkg and Sign the .pkg

productbuild --sign "$PKG_CERTIFICATE" --component Lokal.app /Applications Lokal-Installer.pkg

During this time there is will be a pop-up for password authorization, this is normal.

Notarize the generated .pkg file

xcrun notarytool submit ./Lokal-Installer.pkg --wait --apple-id "your@apple.email.com" --team-id YOUR_TEAM_ID --password "xxxx-xxxx-xxxx-xxxx"

IMPORTANT, if this is your first-time ever notarizing a file, Your notarization progress may be stuck, but DON'T PANIC, cancel the notarization process instead (by pressing control^+C), on my case, I just leave it for two days, then It's just working fine, in fact, someone even said run your notarize when its daytime on California.

Staple the notarized .pkg file

while this is optional, here the reason you might want to stable your pkg file:

  1. Offline Verification: Stapling allows macOS to verify that your app has been notarized even if the user's device is offline.

  2. Improved User Experience: Without stapling, macOS would need to check with Apple's servers every time the app is launched, which could cause delays.

  3. Gatekeeper Approval: A stapled ticket ensures that Gatekeeper immediately recognizes your app as notarized, allowing it to run without warnings.

> xcrun stapler staple Lokal-Installer.pkg
The staple and validate action worked


Please reach me on X if some of the tutorial are not working or need to be updated.

Lokal by Rubi

Start Building with Lokal.so

Lokal leverage Cloudflare Edge's Network to protect your endpoint and speed up your service from anywhere in the world.

Start Building with Lokal.so

Lokal leverage Cloudflare Edge's Network to protect your endpoint and speed up your service from anywhere in the world.

PT. AKSELERASI KECERDASAN BUATAN. © 2024

PT. AKSELERASI KECERDASAN BUATAN. © 2024

PT. AKSELERASI KECERDASAN BUATAN. © 2024

PT. AKSELERASI KECERDASAN BUATAN. © 2024