My Journey to Sign and Notarize Chromium on macOS
András Tokodi

András Tokodi @atokodi

Location:
Budapest, Hungary
Joined:
Mar 1, 2025

My Journey to Sign and Notarize Chromium on macOS

Publish Date: Jun 4
0 0

Code signing and notarization on macOS sound simple — until you try doing it with a behemoth like Chromium. What began as a straightforward attempt to distribute a custom Chromium build quickly spiraled into a maze of entitlements, hardened runtime quirks, and elusive Apple error codes. In this post, I’ll share the pitfalls, gotchas, and hard-won lessons from my (ongoing) battle to get a Chromium build signed and notarized for macOS. If you're heading down this path yourself, consider this your warning—and maybe your roadmap.

With standard Xcode projects, signing and notarization are mostly automated — you tweak a few settings, hit "Archive," and let Xcode handle the rest. Unfortunately, Chromium doesn’t play by those rules. It uses its own custom build system based on gn and ninja, which completely bypasses Xcode. That means you’re on your own when it comes to manually configuring code signing, setting entitlements, and preparing the app for Apple’s notarization service. Your only real option is to replicate what Xcode does—painstakingly — using command-line tools like codesign, spctl, and xcrun altool or notarytool.

Luckily, there are some scripts in the Chromium repo that help with signing and notarizing, but they’re not exactly beginner-friendly. Documentation is sparse, and if you try googling for answers, you’ll mostly find outdated threads or vague references with little actionable detail. There is an official Mac build instructions guide, which is helpful for getting the Chromium source compiled—but it stops short of explaining how to create an installer or package the final app into a DMG.

For that, Chromium has a separate build target located in chrome/installer/mac. To build it, you can run the following command from your Chromium source root:

autoninja -C out/Release chrome/installer/mac
Enter fullscreen mode Exit fullscreen mode

The chrome/installer/mac target doesn’t just spit out a DMG — it creates a Chromium Packaging directory under your build output, which includes several helper tools and scripts for signing and building an installer. There’s also a README on signing tucked in there that’s worth reading, though like much of Chromium’s infrastructure, it assumes a fair bit of prior knowledge.

From this directory, I ended up using two scripts as part of my packaging workflow. The built .app is almost a gigabyte, which makes it a pain to share directly. To create a more manageable .dmg, I used the following command:

out/Mac/Chromium\ Packaging/pkg-dmg --source out/Mac/Chromium.app/ --target out/Mac/Chromium.dmg --sourcefile
Enter fullscreen mode Exit fullscreen mode

The resulting DMG is much smaller than the raw app bundle, making it easier to distribute. However, don’t celebrate just yet — if you try to share that DMG with coworkers or testers, it will likely trigger macOS security errors due to it not being signed or notarized. The ugly workaround? Recipients can manually strip the quarantine flag:

xattr -rd com.apple.quarantine Chromium.dmg
Enter fullscreen mode Exit fullscreen mode

Sure, it works — but let’s face it, asking people to run terminal commands just to open your app isn’t exactly user-friendly or secure.

So what’s the proper solution? The answer is sign_chrome.py — a script built specifically to handle the complexities of signing Chromium properly. But before you can even think about running it, you’ll need to deal with the most dreaded part of the process: Apple certificates and provisioning.

First, you must be enrolled in the Apple Developer Program and have an active developer account. Without that, none of the signing or notarization steps will work. Once you're in, you need to obtain a signing certificate. The easiest way to do that is via Xcode:

  1. Open Xcode > Settings > Accounts
  2. Select your team
  3. Click Manage Certificates
  4. Add a new "Apple Development" certificate

Once added, verify the certificate is available by running:

security find-identity
Enter fullscreen mode Exit fullscreen mode

You should see something like:

 1) ABC123... "Apple Development: Your Name (TEAMID)"
Enter fullscreen mode Exit fullscreen mode

This identity will be used for signing. For notarization you’ll need an App Store Connect credential. Apple has official documentation on notarization, but here’s the condensed version for Chromium:

First, you need to store credentials for notarytool. This means generating a one-time app-specific password from your Apple account (under the “Manage” tab) and running:


xcrun notarytool store-credentials "notarytool-password" \
  --apple-id "<your developer email>" \
  --team-id "TEAMID" \
  --password "<your app-specific password>"
Enter fullscreen mode Exit fullscreen mode

Once your credentials are stored, you're ready to both sign and notarize your build in one go:

out/Mac/Chromium\ Packaging/sign_chrome.py \
  --identity "Apple Development: Your Name (TEAMID)" \
  --development \
  --input out/Mac/ \
  --output out/Mac/packaged \
  --notarize \
  --notary-arg="--keychain-profile" \
  --notary-arg="notarytool-password"
Enter fullscreen mode Exit fullscreen mode

For more options or debugging, you can run the script with --help.

At this point, the script will handle the full signing flow and send the app off to Apple for notarization. It might take a few minutes, so grab a coffee and let it do its thing. Once it finishes, you’ll have a fully signed and notarized Chromium build — finally ready to share with others without triggering macOS security alarms.

So that’s the story of how I wrangled Chromium into a signed and notarized macOS app—wading through sparse documentation, quirky tooling, and the ever-painful Apple developer portal. It took trial, error, and way too much coffee, but the end result is a shareable, properly notarized Chromium build that macOS won’t immediately quarantine. Of course, the struggle doesn’t end here — next up, I dive into the equally delightful process of uploading a Chromium-based Android App Bundle (AAB) to the Play Console, while juggling multiple ABIs. Stay tuned.

Comments 0 total

    Add comment