macOS 签名(debug 构建)

本应用通常通过 scripts/package-mac-app.sh 构建,该脚本现在会:

  • 设置稳定的 debug bundle identifier:ai.openclaw.mac.debug
  • 用该 bundle id 写入 Info.plist(可通过 BUNDLE_ID=... 覆盖)
  • 调用 scripts/codesign-mac-app.sh 对主二进制文件和 app bundle 签名,让 macOS 在重新构建间视为同一个已签名的 bundle,从而保持 TCC 权限(通知、辅助功能、屏幕录制、麦克风、语音识别)。要获得稳定的权限,请使用正式签名身份;ad-hoc 是可选的但不稳定(见 macOS 权限)。
  • 默认使用 CODESIGN_TIMESTAMP=auto;为 Developer ID 签名启用可信时间戳。设置 CODESIGN_TIMESTAMP=off 可跳过时间戳(离线 debug 构建)。
  • 在 Info.plist 中注入构建元数据:OpenClawBuildTimestamp(UTC)和 OpenClawGitCommit(短 hash),让 About 面板能显示构建信息、git commit 和 debug/release 通道。
  • 打包默认使用 Node 24:脚本运行 TS 构建和 Control UI 构建。Node 22 LTS 目前 22.16+ 也可兼容使用。
  • 从环境变量读取 SIGN_IDENTITY。在你的 shell rc 中添加 export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)"(或你的 Developer ID Application 证书)以始终使用你的证书签名。ad-hoc 签名需要通过 ALLOW_ADHOC_SIGNING=1SIGN_IDENTITY="-" 显式选择(不推荐用于权限测试)。
  • 签名后运行 Team ID 审计,如果 app bundle 中有任何 Mach-O 被不同 Team ID 签名则报错。设置 SKIP_TEAM_ID_CHECK=1 可跳过。

用法

# 从仓库根目录
scripts/package-mac-app.sh               # 自动选择身份;找不到则报错
SIGN_IDENTITY="Developer ID Application: Your Name" scripts/package-mac-app.sh   # 正式证书
ALLOW_ADHOC_SIGNING=1 scripts/package-mac-app.sh    # ad-hoc(权限无法持久化)
SIGN_IDENTITY="-" scripts/package-mac-app.sh        # 显式 ad-hoc(同样的问题)
DISABLE_LIBRARY_VALIDATION=1 scripts/package-mac-app.sh   # 仅开发用,Sparkle Team ID 不匹配的变通方案

Ad-hoc 签名说明

使用 SIGN_IDENTITY="-"(ad-hoc)签名时,脚本会自动禁用 Hardened Runtime--options runtime)。这是为了防止应用在加载嵌入的框架(如 Sparkle)时崩溃——这些框架的 Team ID 不同。ad-hoc 签名同时会导致 TCC 权限无法持久化;恢复步骤见 macOS 权限

About 面板的构建元数据

package-mac-app.sh 在 bundle 中嵌入:

  • OpenClawBuildTimestamp:打包时的 ISO8601 UTC 时间
  • OpenClawGitCommit:短 git hash(不可用时为 unknown

About 标签读取这些键来显示版本、构建日期、git commit,以及是否为 debug 构建(通过 #if DEBUG)。代码改动后重新运行打包脚本以刷新这些值。

原因

TCC 权限与 bundle identifier 代码签名绑定。未签名的 debug 构建每次 UUID 不同,导致 macOS 在每次重新构建后忘记权限授予。对二进制文件签名(默认 ad-hoc)并保持固定的 bundle id/路径(dist/OpenClaw.app)可以在构建间保持权限,与 VibeTunnel 方案一致。