Skip to content

fix(release): sign CEF framework as single bundle on macOS#937

Merged
senamakel merged 1 commit into
tinyhumansai:mainfrom
senamakel:fix/cef-macos-framework-codesign
Apr 26, 2026
Merged

fix(release): sign CEF framework as single bundle on macOS#937
senamakel merged 1 commit into
tinyhumansai:mainfrom
senamakel:fix/cef-macos-framework-codesign

Conversation

@senamakel
Copy link
Copy Markdown
Member

@senamakel senamakel commented Apr 26, 2026

Summary

CI-built macOS .app bundles ship CEF + helpers but every embedded webview (Telegram, WhatsApp, Slack, Discord, ...) silently stays on about:blank. Locally-built .app works fine.

Repro: download OpenHuman.app from a release run, launch it, watch stderr:

[ERROR:base/mac/process_requirement.cc:165] Unable to derive validation category for current process. Signature validation of current process failed: NSOSStatusErrorDomain Code=-67030
[ERROR:base/mac/process_requirement.cc:560] ProcessIsSignedAndFulfillsRequirement: Code=-67030
...
[tg][...] idb scan failed: GET http://127.0.0.1:19222/json/version: error sending request

-67030 = errSecCSReqFailed. Chromium calls SecCodeCheckValidity() against its own running process at startup; when that fails, helper processes can't host the URL request context or the remote debugger, so embedded webviews never navigate.

Root cause is in scripts/release/sign-and-notarize-macos.sh. The post-build re-sign step walks into Chromium Embedded Framework.framework and signs each *.dylib / *.so individually with hardened-runtime + the sidecar entitlements plist, then re-seals the framework as a whole. That corrupts the framework's _CodeSignature/CodeResources manifest — inner libs end up with their own designated requirement that doesn't match the categories Chromium expects in process_requirement.cc.

Local cargo tauri build (vendored CEF-aware CLI) signs the framework as a single bundle, which is the Apple-correct way: codesign recursively seals nested libs via the framework's _CodeSignature. That's why the local build passes the runtime self-check and the CI build doesn't.

Fix

  • Sign each *.framework as a single bundle, no --entitlements (frameworks don't carry entitlements).
  • Sign each Helper.app as a bundle and let codesign handle the inner binary, instead of pre-signing the Mach-O separately and then re-signing the bundle around it.

Out of scope (follow-up)

The shared entitlements.sidecar.plist is reused for the main .app, every helper, and the sidecar. It's broad enough to work but conceptually wrong (GPU/Plugin/Alerts helpers don't need allow-jit; the main app shouldn't share the sidecar plist). Splitting per-target plists is hygiene, not the bug — leaving for a follow-up to keep this change focused.

Test plan

  • Trigger Release workflow on this branch (production target)
  • Download the macOS .app artifact, launch it, confirm no process_requirement.cc errors in stderr
  • Open a Telegram account in the app, confirm web.telegram.org actually loads (CDP port 19222 reachable, page leaves about:blank)
  • codesign --verify --deep --strict --verbose=2 OpenHuman.app passes
  • spctl -a -vv -t exec OpenHuman.app reports notarized
  • xcrun stapler validate OpenHuman.app succeeds

Summary by CodeRabbit

  • Chores
    • Refined macOS code signing and notarization process in the release workflow for improved build efficiency.

The post-build re-sign step walked into Chromium Embedded Framework.framework
and signed each *.dylib / *.so individually with hardened-runtime + the
sidecar entitlements plist, then re-sealed the framework. This corrupted the
framework's _CodeSignature manifest. At runtime CEF's
SecCodeCheckValidity self-check failed with -67030 (errSecCSReqFailed) —
process_requirement.cc could not derive a validation category, helper
processes could not host the URL request context or remote debugger, and
every embedded webview (Telegram, WhatsApp, Slack, Discord, ...) stayed on
about:blank in CI-built bundles. Local cargo tauri build worked because the
vendored CEF-aware bundler signs the framework as one unit.

Sign each *.framework as a single bundle with no --entitlements (frameworks
do not carry entitlements; codesign seals nested libs via CodeResources).
Sign each Helper.app as a bundle and let codesign handle its inner binary
instead of pre-signing the Mach-O separately.
@senamakel senamakel requested a review from a team April 26, 2026 08:00
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3494c036-2958-4a15-85f1-b7cadd18de30

📥 Commits

Reviewing files that changed from the base of the PR and between 339f44f and 27b30aa.

📒 Files selected for processing (1)
  • scripts/release/sign-and-notarize-macos.sh

📝 Walkthrough

Walkthrough

The macOS signing script now uses a new codesign_framework() helper to sign frameworks as unified bundles without entitlements, relying on codesign's bundle sealing. This removes previous logic that individually signed nested dylibs/so files and pre-signed helper app inner binaries.

Changes

Cohort / File(s) Summary
macOS Code Signing Script
scripts/release/sign-and-notarize-macos.sh
Introduced codesign_framework() helper function to sign frameworks as single bundles. Removed nested dylib/so individual signing and helper app pre-signing steps; relies on codesign's inherent bundle sealing behavior instead.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Poem

🐰 Framework bundles, sealed with care,
No nested files to sign with flair,
Codesign handles all the rest,
One helper function does its best!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the primary change: signing the CEF framework as a single bundle on macOS, which is the core fix addressing the code signing validation errors in the CI-built .app bundles.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@senamakel senamakel merged commit bdcb425 into tinyhumansai:main Apr 26, 2026
9 checks passed
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
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