fix: sign macOS releases with Developer ID and notarize them - #264
Merged
Conversation
Releases up to v2.4.1 were signed with an Apple Distribution certificate, an App Store submission identity that carries no Developer ID leaf extension, and were never submitted to notarytool. When that certificate was revoked on 2026-08-12 during the signing overhaul in continuum-router, Gatekeeper began reporting CSSMERR_TP_CERT_REVOKED for every installed bssh binary: macOS kills the process on launch (SIGKILL) and deletes the file as malware, which broke every Homebrew installation. This ports the signing and notarization pipeline from continuum-router (lablup/continuum-router#1313), which itself mirrors backend.ai-go. Two composite actions replace the import-codesign-certs plus codesign steps: macos-signing-setup extracts the p12 to a PEM with an OpenSSL selected for pkcs12 -legacy support, rejects any p12 that holds no Developer ID Application certificate, and installs rcodesign; macos-sign-notarize-binary signs a staged copy with the hardened runtime and a pinned reverse-DNS identifier, asserts the resulting authority, runtime flag, and identifier, packages the flat zip with ditto, and gates on notarytool status Accepted. Each of the three released binaries (bssh, bssh-server, bssh-keygen) goes through its own sign-package-notarize call, sealed as BUNDLE_ID, BUNDLE_ID-server, and BUNDLE_ID-keygen respectively. The zip names and flat layout (binary plus man page) are unchanged, so the Homebrew formula and the update_homebrew_formula workflow need no changes. The release now requires APPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, APPLE_ID, APPLE_TEAM_ID, and APPLE_PASSWORD secrets plus the BUNDLE_ID variable on the packaging environment; the old DEV_ID_CERT_P12 and DEV_ID_CERT_PASSWORD secrets are no longer used. The rationale is recorded in the ARCHITECTURE.md Security Model section.
5 tasks
inureyes
added a commit
that referenced
this pull request
Aug 14, 2026
Bumps the version to 2.4.2 and records the release in README.md, CHANGELOG.md, debian/changelog, and the three manpages. No source changed between 2.4.1 and 2.4.2: the release exists to republish the macOS binaries with a Developer ID signature and Apple notarization, since the certificate that signed every earlier macOS build was revoked and macOS now kills and deletes those binaries on launch (#264). The member crate bssh-russh-sftp stays on its own version line at 2.3.0.
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.
Summary
Every macOS release up to v2.4.1 was signed with an
Apple Distribution: Lablup Inc.certificate, an App Store submission identity that carries no Developer ID leaf extension (1.2.840.113635.100.6.1.13), and was never submitted to notarytool. When that certificate was revoked on 2026-08-12 during the signing overhaul in lablup/continuum-router#1313, Gatekeeper began returningCSSMERR_TP_CERT_REVOKEDfor every installed bssh binary: macOS kills the process on launch (SIGKILL, exit 137), shows the "will damage your computer" dialog, and deletes the file as malware. Every Homebrew installation on macOS is currently broken this way.This PR ports the signing and notarization pipeline from continuum-router (itself mirrored from backend.ai-go) so official macOS binaries are signed with a Developer ID Application certificate and notarized.
Changes
.github/actions/macos-signing-setup: extracts the Developer ID p12 to a PEM (selecting an OpenSSL that supportspkcs12 -legacyby capability, since Apple's LibreSSL has no such option), rejects a p12 that holds no Developer ID Application certificate before anything is signed, and installs rcodesign, which reads the PEM directly and needs no keychain or GUI session..github/actions/macos-sign-notarize-binary: signs a staged copy with the hardened runtime and a pinned reverse-DNS identifier, asserts theDeveloper ID Applicationauthority, the runtime flag, and the identifier after signing, packages the flat zip withditto, submits it tonotarytool --wait, and gates onstatus: Accepted. A bare Mach-O cannot be stapled, so the ticket stays on Apple's servers and Gatekeeper resolves it online.release.yml: replace theimport-codesign-certsandcodesign --sign "Distribution"steps (the substring match is what selected the wrong certificate) with one setup call and three sign-package-notarize calls, one per released binary (bssh,bssh-server,bssh-keygen), sealed asBUNDLE_ID,BUNDLE_ID-server, andBUNDLE_ID-keygen. The unused job-levelBIN_NAME/BUNDLE_IDenv block is removed.ARCHITECTURE.md: record the pipeline and its rationale under Security Model.The zip names and flat layout (binary plus man page) are unchanged, so the Homebrew formula and
update_homebrew_formula.ymlneed no changes.Release prerequisites
The
packagingenvironment needsAPPLE_CERTIFICATE(base64 Developer ID Application p12),APPLE_CERTIFICATE_PASSWORD,APPLE_ID,APPLE_TEAM_ID,APPLE_PASSWORD(app-specific password), and theBUNDLE_IDvariable (com.lablup.bssh). The oldDEV_ID_CERT_P12/DEV_ID_CERT_PASSWORDsecrets are no longer used. A wrong certificate now fails the release at the setup step instead of shipping quietly.Tests
actionlintpasses on.github/workflows/release.yml(validates the local action references and inputs).Risk notes
notarytool --waitround per binary (three total) to the macOS job.