Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

macOS Signing Overview

Shipping a macOS app to users outside the App Store requires three steps:

  1. Code signing — digitally sign your binary with a Developer ID certificate so macOS recognizes it as trusted
  2. Notarization — submit the signed artifact to Apple’s servers for automated malware scanning
  3. Stapling — attach the notarization ticket to the artifact so it works offline

Skip any of these and users see the dreaded “Apple could not verify” dialog — or worse, Gatekeeper blocks the app entirely.

What cargo-codesign handles

cargo codesign macos runs the full pipeline:

.app bundle ──► sign inner binaries ──► sign .app
                                            │
                          ┌─────────────────┼─────────────────┐
                          │                                   │
                     --as zip                            --as dmg
                          │                                   │
                   zip .app (submit)                    zip .app (submit)
                          │                                   │
                   notarize .app                        notarize .app
                          │                                   │
                    staple .app                          staple .app
                          │                                   │
                   create output zip                     create DMG
                          │                                   │
                   ✓ Ready to ship                    sign + notarize DMG
                                                              │
                                                         staple DMG
                                                              │
                                                       ✓ Ready to ship

Before you start

You need:

  1. A Developer ID Application certificate — see Setting Up Credentials
  2. A built .app bundle — cargo-codesign does not build or bundle. See below.
  3. Apple credentials for notarization — either an API key or Apple ID + app-specific password

Building a .app bundle (not a cargo-codesign concern)

Before you can sign, you need a .app bundle. Here’s what that looks like:

# Minimal .app structure
mkdir -p "MyApp.app/Contents/MacOS"
mkdir -p "MyApp.app/Contents/Resources"

# Copy your binary
cp target/release/myapp "MyApp.app/Contents/MacOS/myapp"

# Copy metadata
cp Info.plist "MyApp.app/Contents/"
cp AppIcon.icns "MyApp.app/Contents/Resources/"

Tools like cargo-bundle and cargo-packager automate this. Your project may also have a custom bundle script.

For universal binaries (Intel + Apple Silicon), create both architectures and combine them before bundling:

cargo build --release --target x86_64-apple-darwin
cargo build --release --target aarch64-apple-darwin

lipo -create \
  target/x86_64-apple-darwin/release/myapp \
  target/aarch64-apple-darwin/release/myapp \
  -output target/universal-apple-darwin/release/myapp

Once you have a .app, cargo-codesign takes over.

Three modes

ModeCommandWhat it does
App mode (zip)cargo codesign macos --app "MyApp.app" --as zipSign app → notarize → staple → output zip
App mode (dmg)cargo codesign macos --app "MyApp.app" --as dmgSign app → notarize → staple → create DMG → notarize DMG → staple DMG
Bare binary modecargo codesign macosDiscover binaries via cargo metadata, sign each, copy to target/signed/

Most GUI apps use app mode. Use --as zip for Homebrew cask distribution, --as dmg (default) for website downloads. CLI tools use bare binary mode.