macOS Code Signing for Debug Builds

This page covers the code signing steps for macOS debug builds generated by the packaging scripts. Developers need this to ensure consistent signing and TCC permissions across builds.

Read this when

  • Building or signing mac debug builds

mac signing (debug builds)

After scripts/package-mac-app.sh compiles and bundles the application to a predetermined location (dist/OpenClaw.app), it invokes scripts/codesign-mac-app.sh to apply a code signature. TCC permissions are linked to both the bundle identifier and the code signature; maintaining consistency for both (and keeping the app in the same directory) across builds prevents macOS from invalidating TCC grants for notifications, accessibility, screen recording, microphone, and speech.

  • The debug bundle identifier is ai.openclaw.mac.debug by default, which can be changed using BUNDLE_ID=....
  • Supported Node versions are >=22.22.3 <23, >=24.15.0 <25, or >=25.9.0 (from the repository package.json engines). The packager also constructs the Control UI at pnpm ui:build.
  • A legitimate signing identity is required by default; the codesign script terminates with an error when no identity is found and ALLOW_ADHOC_SIGNING is not defined. Ad-hoc signing via SIGN_IDENTITY="-" must be explicitly enabled, and it does not preserve TCC permissions across rebuilds. Refer to macOS permissions.
  • SIGN_IDENTITY is pulled from environment variables (for instance, export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)" or a Developer ID Application certificate). When it is absent, codesign-mac-app.sh picks an identity using this priority: Developer ID Application, Apple Distribution, Apple Development, then the first valid codesigning identity it encounters.
  • Trusted timestamps are activated by default (CODESIGN_TIMESTAMP=auto) only for Developer ID Application signatures. To force a specific behavior, set on or off.
  • The Info.plist file receives OpenClawBuildTimestamp (ISO8601 UTC) and OpenClawGitCommit (a short hash, or unknown if one is not available) so the About tab can display the build, git commit, and debug or release channel.
  • After signing, a Team ID audit runs and fails the build if any Mach-O file inside the bundle has a mismatched 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

The Hardened Runtime is disabled by SIGN_IDENTITY="-" (using --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 prevent TCC permissions from persisting; consult macOS permissions for instructions on recovery.

Build metadata for About

The About tab retrieves OpenClawBuildTimestamp and OpenClawGitCommit from Info.plist to present the version, build date, git commit, and whether the build is a DEBUG configuration (determined by #if DEBUG). After modifying code, rerun the packager to update these values.

439 words · updated Jul 27, 2026