Notarization proves Apple has scanned your binaries; stapling embeds the ticket so Gatekeeper can validate offline. Teams that skip the decision and “always staple” waste minutes on every build; teams that “never staple” learn about air-gapped labs the hard way. On Mac mini M4 CI runners—especially dedicated hosts from NodeMac in Hong Kong, Japan, Korea, Singapore, or the US—publish a matrix that ties staple policy to distribution channel, network assumptions, and artifact type. This article gives two matrices, eight rollout steps, and FAQ structured data aligned with how security reviewers actually read pipelines.
Storage and retention context: disk & artifact retention and lockfile-hashed caches. When engineers need a GUI to compare two signed trees, use VNC on the same NodeMac host. Pricing; help.
Gatekeeper: online ticket lookup vs stapled ticket
macOS can notarize successfully yet still surprise users if the ticket is not stapled and the machine cannot reach Apple's services at first launch. Conversely, stapling mutates the outer container (for example a .dmg), which invalidates naive checksum gates if you compute hashes too early. Your CI policy must name which checksum is the audit artifact (pre-staple) and which blob ships to customers (post-staple).
- Ticket-only: fastest iteration when lab Macs have reliable egress and you control re-check policies.
- Stapled: default for customer-facing disk images, offline installers, and field laptops.
- Hybrid: staple only release channels; keep nightly builds ticket-only with explicit banners.
Matrix A: staple vs ticket by distribution path
| Artifact & path | Staple? | Rationale |
|---|---|---|
| Developer .dmg on USB kiosks | Yes | Offline Gatekeeper path; avoid first-launch CDN dependency |
| Internal CI smoke install on wired lab Macs | Optional | If egress monitored and failures acceptable, ticket-only speeds loops |
| MDM-delivered pkg with post-install stapling | Either | Document who staples—pipeline vs MDM—to avoid double work |
| App Store upload pipeline | Follow Apple transport docs | Different consumer; do not cargo-cult desktop DMG rules |
Matrix B: CI stage ordering and verification
| Stage | Command family | Pass criteria |
|---|---|---|
| Sign | codesign hardened runtime flags per entitlements matrix |
codesign --verify --deep --strict clean |
| Notarize | notarytool submit + poll |
Log shows Accepted; submission id archived |
| Staple | xcrun stapler staple |
stapler validate OK on clean VM |
| Smoke | Launch app from mounted image | No “damaged” dialog; telemetry matches expected version |
Numeric guardrails
- Timeout budget: allow at least 25 minutes wall time for notary poll on release trains; shorter on feature branches only if you accept flakes.
- Parallel submissions: cap concurrent notary jobs per host to 2 to avoid Apple-side throttling colliding with Xcode peaks.
- Artifact immutability: upload stapled objects to a new object key; never overwrite in place.
Audit tip: attach both the notary submission id and the SHA-256 of the pre-staple artifact to the change ticket. Stapling is not a substitute for signing logs.
Eight rollout steps
- Inventory channels where each build type ships (lab, customer, MDM).
- Encode matrix in pipeline templates—not tribal knowledge in Slack.
- Split jobs: build/sign, notarize, staple, publish as separate steps with distinct caches.
- Add VM smoke that disables outbound Apple endpoints optionally to detect missing staples.
- Store logs for notarytool in the same retention bucket as other signing evidence.
- Rotate signing certs on a calendar; re-run matrix validation after every rotation.
- Train on-call to read stapler errors vs notarytool errors—different owners.
- Provision dedicated M4 hosts per region when queue times force risky shortcuts—NodeMac removes hardware contention from the policy debate.
FAQ
When must CI staple?
When users install offline or from networks you do not control. Keep ticket-only for well-connected internal loops if documented.
Does stapling break checksum caching?
Yes—hash before staple for audit; treat post-staple blob as the shipping artifact with its own checksum.
What if stapler runs too early?
Gatekeeper rejects damaged apps. Enforce sign → notarize → verify → staple → validate order.