Stop stamping hardened runtime onto ad-hoc builds - #4
Merged
Conversation
v0.0.1 could not be opened by anyone. The DMG installed, the app landed in /Applications, and it exited before drawing a window. The ad-hoc signing step passed --options runtime, matching what electron-builder applies to a certificate-signed build on the reasoning that the two should differ only in the identity. That reasoning is what shipped an unopenable app. Hardened runtime plus an ad-hoc signature is fatal to Electron. Electron validates its helper processes' code signature, that validation needs the task port, and hardened runtime denies it: codesign_util.cc] task_name_for_pid: (os/kern) failure (5) The evidence is a pair of flag sets on one machine. The release was flags=0x10002(adhoc,runtime) and would not start. The dev build, which runs perfectly and has all along, is flags=0x20002(adhoc,linker-signed) — the same ad-hoc signature without hardened runtime. Hardened runtime is mandatory for notarization and buys nothing without a real identity, so it belongs on the signed path only, where it already is. TCC is unaffected: grants key to a stable signature, which this still produces, not to hardened runtime. The step now also fails the build if the flag turns up anyway, because the symptom of getting this wrong is a green release that nobody can open — which is exactly how it shipped the first time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v0.0.1 could not be opened by anyone. The DMG installed, the app landed in
/Applications, and it exited before drawing a window. Confirmed on a wiped machine installing from the release.Cause
The ad-hoc signing step passed
--options runtime, matching what electron-builder applies to a certificate-signed build — on the reasoning that the two should differ only in the identity. That reasoning is what shipped an unopenable app.Hardened runtime plus an ad-hoc signature is fatal to Electron. Electron validates its helper processes' code signature, that validation needs the task port, and hardened runtime is what denies it:
The evidence is a pair of flag sets on one machine:
0x10002(adhoc,runtime)npm run dev)0x20002(adhoc,linker-signed)Same ad-hoc signature. The only difference is hardened runtime.
Worth noting the bundle was never corrupt —
codesign --verify --deep --strictreported valid on disk and satisfies its Designated Requirement throughout. It's the signature type, not its integrity.Fix
Drop
--options runtimefrom the ad-hoc path only. It stays on the signed path, where it's mandatory for notarization and where it belongs. Entitlements are still applied.TCC is unaffected — grants key to a stable signature, which this still produces, not to hardened runtime. That was the original concern behind matching the flags, and it doesn't apply.
The step now also fails the build if the flag appears anyway. The symptom of getting this wrong is a green release nobody can open, which is precisely how it shipped the first time.
What this does and doesn't fix
It makes unsigned builds launchable. It does not remove the Gatekeeper dialog — that needs a Developer ID certificate and notarization, which
build.ymlalready performs when its six signing secrets are present. Until then the cask strips the quarantine flag (guarded on the signature, so it becomes a no-op once builds are notarized).🤖 Generated with Claude Code