同印方载,异印即拒 · Accept host-matched re-signed macOS artifacts - #59
Merged
eric8810 merged 5 commits intoAug 5, 2026
Merged
Conversation
Downstream macOS packaging pipelines re-sign every Mach-O in the app bundle (including light_ocr_node.node and the ONNX Runtime dylib) with a Developer ID or ad-hoc identity while notarizing, which rewrites LC_CODE_SIGNATURE and changes both file size and sha256. The strict runtime-descriptor gate therefore rejected intact, verified binaries. On macOS only, treat a Mach-O whose code signature verifies (codesign --verify --strict) AND whose signing identity matches the host process (same TeamIdentifier as process.execPath, or both ad-hoc signed) as an equivalent integrity proof. All other mismatches keep the existing package_load_failed contract: no silent fallback, no partial state, and win32/linux payloads keep the strict bytes+sha256 gate. The descriptor record format checks, the native directory inventory check, and the post-load validateNativeContract() ABI check are unchanged. Ad-hoc acceptance is deliberately macOS-only and documented because ad-hoc signatures are reproducible by anyone. Add adaptive macOS integration tests (policy matrix, unsigned mutation rejection, ad-hoc re-signing per host identity, non-Mach-O rejection, Developer ID round-trip when a keychain identity is available) and bump the release closure to conservative patch versions (0.5.7 / runtime 0.1.7 / tiny+medium 0.1.6 / document 0.1.3).
Validate the descriptor digest syntax before the macOS signed-mutation fallback can accept a size-divergent artifact. Add a macOS regression test that keeps malformed records fail-closed.
Update the workflow input and offline smoke package references to the patch versions declared by this release candidate.
Run the signed-artifact policy on both the default macOS Node host and an ad-hoc re-signed host during package smoke. Correct the positive-path assertions uncovered by the new gate and align the build-and-release guide with the current package closure.
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
@arcships/light-ocr-darwin-*native packages are re-signed by downstream macOS packaging pipelines: osx-sign rewrites theLC_CODE_SIGNATUREblob of every Mach-O underContentswith--force(includinglight_ocr_node.nodeandlibonnxruntime.1.22.0.dylib), changing both file size and sha256. The runtime descriptor's strict bytes+sha256 gate then rejects intact binaries withpackage_load_failed: Descriptor artifact byte count mismatch.What changed (
packages/runtime/src/load-native.cjs):stats.size === bytesandsha256(file) === sha256→ load (unchanged path).codesign --verify --strictpasses,process.execPath): identicalTeamIdentifier, or both sides ad-hoc signed.package_load_failed, byte count / hash mismatch) — no silent fallback, no partial state.validateNativeContract()ABI check are unchanged.Security boundary: ad-hoc signatures are reproducible by anyone, so the both-ad-hoc branch is a documented, macOS-only relaxation. The host-match rule rejects payloads re-signed by any other identity.
Electron integration (no config required)
Nothing changes for Electron apps — the loader auto-adapts to the host signature:
package_load_failed(by design)node_modules/@arcships/light-ocr-darwin-*/native/*.nodeand*.dylibwith your Developer ID now loads instead of failing.codesignis a stock macOS binary and the loader only verifies (no keychain, no certificate required).Verification
bindings/node/test/signed-artifact.test.cjs: policy matrix (all platforms) + macOS integration with realcodesign(pristine accept; unsigned mutation reject on the size and hash branches; ad-hoc re-sign accepted when the host is ad-hoc, rejected when the host is Developer ID signed; non-Mach-O mutation reject; Developer ID round-trip self-skips when a keychain identity is unavailable — the suite never hangs on a keychain prompt).3AA79YWT4C): pristine pass; tampered-unsigned rejected; ad-hoc re-sign rejected (different signer).CHANGELOG.md, README (EN/ZH), npm package README, and decision record D117 updated.Checklist
CHANGELOG.mdwere updated for user-visible changes.