macOS Signing
Signing steps for macOS debug builds generated by packaging scripts
This app is usually built from ''''scripts/package-mac-app.sh'''', which now:
- sets a stable debug bundle identifier: ''ai.openclaw.mac.debug''
- writes Info.plist with that bundle id (override via ''BUNDLE_ID=...'')
- calls ''''scripts/codesign-mac-app.sh'''' to sign main binary and app bundle so macOS treats each rebuild as same signed bundle and keeps TCC permissions (notifications, accessibility, screen recording, mic, speech). For stable permissions, use a real signing identity; ad-hoc is opt-in and fragile (see ''macOS permissions'').
- uses ''CODESIGN_TIMESTAMP=auto'' by default; it enables trusted timestamps for Developer ID signatures. Set ''CODESIGN_TIMESTAMP=off'' to skip timestamping (offline debug builds).
- injects build metadata into Info.plist: ''OpenClawBuildTimestamp'' (UTC) and ''OpenClawGitCommit'' (short hash) so About pane can show build, git, and debug/release channel.
- Packaging requires Node 22+: script runs TS builds and Control UI build.
- reads ''SIGN_IDENTITY'' from environment. Add ''export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)"'' (or your Developer ID Application cert) to your shell rc to always sign with your cert. Ad-hoc signing requires explicit opt-in via ''ALLOW_ADHOC_SIGNING=1'' or ''SIGN_IDENTITY="-"'' (not recommended for permission testing).
- runs a Team ID audit after signing and fails if any Mach-O inside app bundle is signed by a different Team ID. Set ''SKIP_TEAM_ID_CHECK=1'' to bypass.
Usage
scripts/package-mac-app.sh # auto-selects identity; errors if none found SIGN_IDENTITY="Developer ID Application: Your Name" scripts/package-mac-app.sh # real cert ALLOW_ADHOC_SIGNING=1 scripts/package-mac-app.sh # ad-hoc (permissions will not stick) SIGN_IDENTITY="-" scripts/package-mac-app.sh # explicit ad-hoc (same caveat) DISABLE_LIBRARY_VALIDATION=1 scripts/package-mac-app.sh # dev-only Sparkle Team ID mismatch workaround
#
Ad-hoc Signing Note
When signing with ''SIGN_IDENTITY="-"'' (ad-hoc), script automatically disables ''Hardened Runtime'' (''--options runtime''). This is necessary to prevent crashes when app attempts to load embedded frameworks (like Sparkle) that do not share same Team ID. Ad-hoc signatures also break TCC permission persistence; see ''macOS permissions'' for recovery steps.
Build metadata for About
''package-mac-app.sh'' stamps bundle with:
- ''OpenClawBuildTimestamp'': ISO8601 UTC at package time
- ''OpenClawGitCommit'': short git hash (or ''unknown'' if unavailable)
The About tab reads these keys to show version, build date, git commit, and whether it's a debug build (via ''#if DEBUG''). Run packager to refresh these values after code changes.
Why
TCC permissions are tied to bundle identifier _and_ code signature. Unsigned debug builds with changing UUIDs were causing macOS to forget grants after each rebuild. Signing binaries (ad‑hoc by default) and keeping a fixed bundle id/path (''dist/OpenClaw.app'') preserves grants between builds, matching VibeTunnel approach.