DevOps / CI·CD 9. April 2026

iOS/macOS-Notarisierung mit notarytool & stapler auf einem headless gemieteten Cloud-Mac (2026)

MacXCode Engineering Team ~20 Min. Lesezeit

Distributing a signed macOS app, helper tool, or notarized .dmg outside the App Store still passes through Apple’s notarization service. On a leased bare-metal Apple Silicon cloud Mac in Hong Kong, Japan, Korea, Singapore, or the United States, you usually automate over SSH — no local UI. This 2026 runbook maps xcrun notarytool and xcrun stapler to that reality: credentials in the login keychain, non-interactive submits, explicit log retention, and a hard CI gate before you upload to customers or attach to a mobile pipeline. Pair it with remote Archive & export, signing optimization, and CLT vs full Xcode when you choose toolchain depth.

Why Teams Notarize on Dedicated Cloud Macs

  • Latency to Apple APIs — placing the builder near your chosen region reduces tail latency on submit and log fetch.
  • Reproducible environment — same NVMe, same Xcode patch, same keychain layout every nightly.
  • Separation from laptops — notarization does not compete with Zoom + Slack on a developer machine.
Rule: Treat notarization like any other CI step — pin Xcode, archive submission UUID + JSON log, and fail the job if stapler validate is not clean.

Pain Points Teams Hit on Headless Builders

  • Keychain prompts that never appear — SSH sessions do not surface GUI dialogs; unattended jobs fail until you unlock with security unlock-keychain (or run under a CI-only user whose keychain is pre-authorized for codesign and notarytool).
  • ZIP layout mistakes — flattening a bundle, duplicating MacOS, or stripping extended attributes before upload yields “Invalid” or cryptic signature errors in the notarization log.
  • Silent stapler skips — a build can be “Accepted” in Apple’s service yet still alarm Gatekeeper for customers in SG or US if you never ran stapler staple on the artifact they download.
  • Parallel lane contention — three release branches each submitting 400 MB zips without a mutex can saturate uplink on a 1 Gbps NIC and make tail latency look like an Apple outage.
  • Audit gaps — without storing submission id + JSON, security reviews cannot reconstruct what was notarized on 2026-04-09 versus what shipped.

Choose the Right Artifact Shape

macOS distribution is not iOS TestFlight. Pick a packaging rule per type and document it in your runbook so operators in HK / JP / KR do not improvise under pressure.

Deliverable Typical submit Staple target Gotcha
Signed .app ditto -c -k --keepParent MyApp.app MyApp.zip The bundle directory after acceptance Hardened runtime + entitlements must match the Developer ID identity
.dmg Submit the DMG (or follow Apple’s documented container flow for your toolchain) The DMG file customers mount Volume layout and code signature on the enclosed app must both be coherent
Flat .pkg Output of productbuild / installer pipeline The .pkg on disk Component package IDs and receipts drive support tickets if mis-versioned
Concrete numbers for capacity planning: Expect roughly 2–8 minutes wall time for a typical small-to-medium app notarization (queue-dependent), plus 30–90 seconds for staple + validate on local NVMe. Reserve 5–15 GB scratch per parallel lane (zip + extracted copy + logs). On an M4 leased host, CPU is rarely the bottleneck — network and disk spikes are.

Prerequisites on the Cloud Mac

Requirement Notes
notarytool available Ships with recent Xcode / CLT; verify with xcrun notarytool --version
Signing identity Developer ID Application (macOS binaries) — align with your export pipeline
App Store Connect API key Issuer ID, Key ID, .p8 file — stored via keychain profile, not plaintext in repo
Unattended keychain SSH session user must load the login keychain or use security unlock-keychain in a controlled secret step

Store API Credentials for notarytool

One-time (interactive or secured bootstrap) store of credentials under a profile name, for example ac-notary:

xcrun notarytool store-credentials "ac-notary" --key ~/AuthKey_XXXXXX.p8 --issuer <issuer-uuid> --key-id <key-id>

Prefer a dedicated CI user on the leased Mac so the login keychain is not shared with human VNC experiments. Rotate the .p8 on the same calendar as your other ASC API keys.

Submit the Zip and Wait

Zip the .app (preserve symlinks carefully — use ditto -c -k --keepParent MyApp.app MyApp.zip for typical bundles):

xcrun notarytool submit MyApp.zip --keychain-profile "ac-notary" --wait

If you split wait and poll in CI, capture the submission id from JSON output and call xcrun notarytool log <id> --keychain-profile "ac-notary" until status settles. Save that log under your artifacts bucket.

Parsing tip: pipe notarytool submit output through jq (or your language’s JSON decoder) and assert three fields on every green build: id, status, and message summary. When status is Invalid, the log often references a specific path inside the zip — keep the original zip alongside the log so you can diff against a known-good archive from the same Xcode pin.

Throttle policy: serialize notarization stages per host if you observe HTTP 429 or repeated timeouts; a simple file lock under /tmp or a CI queue depth of 1 per Mac often stabilizes flaky nights.

Staple and Validate

After Apple accepts the submission:

xcrun stapler staple MyApp.app

xcrun stapler validate MyApp.app

For disk images, follow Apple’s current guidance for your artifact type; always end with validate so Gatekeeper checks do not surprise users in SG or US.

Order matters: staple only after Apple reports success. If you rebuild or re-sign locally after acceptance, you must re-submit — stapler cannot “fix” a drifted signature.

Common Failures and What to Check First

Symptom First checks Typical fix
Unable to authenticate from notarytool Profile name spelling; keychain unlocked; .p8 path readable by CI user Re-run notarytool store-credentials; rotate ASC API key if expired
Log shows “The signature of the binary is invalid” Deep codesign verify on the app before zipping; quarantine flags Rebuild export with correct Developer ID; use ditto zip, not Finder “Compress”
stapler validate fails on DMG Stapled the wrong file; DMG mounted during staple Unmount volumes; staple the DMG path you ship; re-validate
Infinite “In Progress” in poll loop Clock skew on VM; network egress blocked to Apple endpoints Sync NTP; allowlist Apple notary endpoints on firewall; cap retry backoff at 15 minutes

CI Gate Checklist

  1. Fail if notarytool submit exits non-zero.
  2. Attach submission id + full JSON log to the build record (retention ≥ your compliance window).
  3. Fail if stapler validate errors on the exact binary you intend to publish.
  4. Record Xcode build string and notarytool version in the same artifact manifest.
  5. Checksum (shasum -a 256) the stapled artifact before upload to CDN or MDM.
  6. Optionally run a spctl assessment on a clean VM slice as a final consumer simulation.

FAQ

Question Answer
Is this the same as iOS App Store upload? No — notarization targets macOS distribution outside the Mac App Store (and related tooling). iOS IPAs use different App Store Connect paths; see Archive runbook.
1 TB vs 2 TB for notarize jobs? Large .zip artifacts + logs + multiple Xcode copies eat NVMe; size up before you parallelize. See pricing.
Do I need full Xcode or only CLT? notarytool ships with modern CLT, but teams often want full Xcode on the same host for archive + export — compare trade-offs in CLT vs full Xcode.
Should notarization share a host with xcodebuild? It can, but isolate with separate workspaces and a mutex so signing and zip do not race; see parallel job layout.
How do I debug without VNC? Pull logs first; if you must inspect GUI-only tools, use VNC briefly on the leased Mac, then return to SSH automation.

Why a Leased Mac mini M4 Fits Notarization CI

Notarization workloads are bursty: you compress multi-hundred-megabyte bundles, upload to Apple, poll APIs, then staple and validate on fast storage. A Mac mini M4 on MacXCode gives you native Apple Silicon behavior for xcrun, predictable NVMe latency for temporary zips, and geographic choice across Hong Kong, Japan, Korea, Singapore, and the United States so data paths align with your compliance story and CDN egress. You avoid buying depreciating hardware while keeping SSH (and optional VNC) parity with a desk machine — ideal for a 24/7 lane that should never compete with a laptop login keychain.

Rented nodes also let you pin images: same Xcode build, same notarytool semantics every nightly. When Apple tightens notarization rules, promote one fleet slice, prove green builds, then roll forward. Pair host sizing with pricing for disk tiers; keep interactive debugging on VNC occasional while production stays headless.

Bottom line: a headless leased Mac mini M4 is a sane place to run notarytool + stapler on a schedule — if you treat keychain access and logs as first-class CI concerns. Next: SSH help or expand parallel build isolation so notarize never races a signing job.

Bare-Metal-Mac für Notarisierung + Xcode

HK · JP · KR · SG · US · SSH / VNC