macOS Debug Build Signing for OpenClaw

This page explains how packaging scripts sign macOS debug builds, including bundle ID defaults, Node version requirements, and ad-hoc signing opt-in. Developers rebuilding the app need this to preserve TCC permissions.

Read this when

  • Building or signing mac debug builds

mac signing (debug builds)

scripts/package-mac-app.sh compiles and packages the application to a fixed location (dist/OpenClaw.app), then invokes scripts/codesign-mac-app.sh to sign it. TCC permissions are bound to the bundle ID and code signature; keeping both unchanged (and the app at a fixed path) between rebuilds prevents macOS from revoking TCC grants (notifications, accessibility, screen recording, microphone, speech).

  • The debug bundle identifier defaults to ai.openclaw.mac.debug (override using BUNDLE_ID=...).
  • Node versions: >=22.22.3 <23, >=24.15.0 <25, or >=25.9.0 (repository package.json engines). The packager also builds the Control UI (pnpm ui:build).
  • By default, a real signing identity is required; the codesign script exits with an error if none is found and ALLOW_ADHOC_SIGNING is not set. Ad-hoc signing (SIGN_IDENTITY="-") requires explicit opt-in and does not preserve TCC permissions across rebuilds. Refer to macOS permissions.
  • Reads SIGN_IDENTITY from the environment (for example, export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)" or a Developer ID Application certificate). Without it, codesign-mac-app.sh automatically selects an identity in this order: Developer ID Application, Apple Distribution, Apple Development, then the first valid codesigning identity found.
  • CODESIGN_TIMESTAMP=auto (default) enables trusted timestamps only for Developer ID Application signatures. Set on or off to force either behavior.
  • Stamps Info.plist with OpenClawBuildTimestamp (ISO8601 UTC) and OpenClawGitCommit (short hash, unknown if unavailable) so the About tab can display build, git, and debug or release channel.
  • Runs a Team ID audit after signing and fails if any Mach-O inside the bundle has a different Team ID. Set SKIP_TEAM_ID_CHECK=1 to skip this check.

Usage

# from repo root
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

SIGN_IDENTITY="-" disables the Hardened Runtime (--options runtime) to avoid crashes when the app loads embedded frameworks (such as Sparkle) that do not share the same Team ID. Ad-hoc signatures also break TCC permission persistence; see macOS permissions for recovery steps.

Build metadata for About

The About tab reads OpenClawBuildTimestamp and OpenClawGitCommit from Info.plist to show version, build date, git commit, and whether the build is DEBUG (via #if DEBUG). Re-run the packager after code changes to refresh these values.