Skip to content

fix(desktop): seal macOS release bundles#97

Merged
steipete merged 1 commit into
mainfrom
fix/macos-bundle-seal
Jul 18, 2026
Merged

fix(desktop): seal macOS release bundles#97
steipete merged 1 commit into
mainfrom
fix/macos-bundle-seal

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Summary

  • replace unsigned macOS release packaging with fail-closed Foundation Developer ID signing and hardened runtime
  • notarize and staple each architecture before Electron Builder creates ZIP/DMG artifacts, with the required 10-minute single retry for connectTimeout
  • verify the stable bundle requirement, nested signatures, resource seal, Gatekeeper assessment, notarization ticket, archive architecture, and checksums locally and again from the draft release on a clean macOS runner
  • keep private signing keys off GitHub-hosted runners; unsigned PR previews remain explicitly separate from official release candidates

Root cause

The v0.2.0 release workflow set CSC_IDENTITY_AUTO_DISCOVERY=false and never supplied a signing identity. Electron Builder therefore preserved Electron's linker/ad-hoc executable signatures but never created an outer app resource seal. The shipped app reported identifier Electron, no team, and Sealed Resources=none; strict verification failed with code has no resources but signature indicates they must be present.

Proof

  • pnpm check
  • pnpm test:desktop
  • shellcheck apps/desktop/scripts/package-macos-release.sh apps/desktop/scripts/verify-macos-app.sh apps/desktop/scripts/verify-macos-release.sh
  • actionlint .github/workflows/release.yml
  • AutoReview: clean, no accepted/actionable findings
  • real arm64 app signed as chat.clickclack.desktop by Team FWJYW4S8P8, hardened runtime enabled, Sealed Resources version=2
  • codesign --verify --strict --deep --verbose=4 ClickClack.app: valid on disk and satisfies its designated requirement
  • explicit identifier/certificate requirement verification: passed

Apple accepted both notarization uploads but the client received HTTPClientError.connectTimeout after the mandated 10-minute wait and single retry; both submissions remained in progress at closeout. The pipeline correctly stopped before producing release archives. Consequently, local spctl reports source=Unnotarized Developer ID until one of those existing submissions completes and a ticket can be stapled. No further submission was attempted.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 329e364dff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

echo "release checkout is not clean" >&2
exit 1
fi
git -C "$repo" tag -v "$tag" >/dev/null 2>&1 || {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pin the authorized release-tag signing key

When the maintainer keyring contains a public key belonging to any contributor or other unapproved signer, git tag -v succeeds for that key's cryptographically valid signature even if the key is not trusted for releases; its help only describes -v as “verify tags,” not authorize the signer. An attacker able to publish such a tag could therefore have arbitrary code signed with the Foundation Developer ID certificate. Check the verified signer's fingerprint against an explicit release-key allowlist before packaging.

Useful? React with 👍 / 👎.

@steipete
steipete merged commit 146f762 into main Jul 18, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant