Gatekeeper 排障
口径说明
融云公开文档不覆盖 macOS 原生 SDK 与桌面交付链(dmg / 代码签名 / 公证 / 分发 / Gatekeeper);本页为本项目按 Apple 与 Electron 官方实践补齐的接入文档。
Gatekeeper 是 macOS 的启动安全机制:未签名、签名无效或未公证的应用会被拦截。排障的关键是先分清“签名问题”“公证问题”还是“隔离属性问题”,不要一上来就教用户执行 `xattr` 绕过。
症状对照
| 提示 / 现象 | 含义 | 正确处置 |
|---|---|---|
| “无法打开,因为无法验证开发者” | 未签名或签名不受信任 | 改用 Developer ID 签名并公证;不要发布 ad-hoc 包 |
| “已损坏,无法打开” | 签名损坏、包内容被改、或下载不完整 | 重新打包签名;校验 sha256;`codesign --verify` 定位 |
| “Apple 无法验证是否包含恶意软件” | 已签名但未公证 / 公证失败 | 重新提交公证并 stapling |
| 首次启动被拦截,右键打开可运行 | 包已公证但带隔离属性 | 正常现象(用户确认一次即可);发布页给出说明 |
| 终端 `open` 能启动,Finder 双击不行 | 通常为隔离属性或权限问题 | 检查 `xattr`、文件权限与 `spctl` 评估结果 |
诊断命令
Shell
# 1) Gatekeeper 评估
spctl -a -vvv "My Desktop.app"
# 2) 签名校验(含嵌套组件)
codesign --verify --deep --strict --verbose=2 "My Desktop.app"
codesign -dv --verbose=4 "My Desktop.app"
# 3) 公证票据
xcrun stapler validate "My Desktop.app"
# 4) 隔离属性(下载来的包会带 com.apple.quarantine)
xattr -l "My Desktop.app"
# 5) 查看系统拦截日志(复现时另开终端)
log stream --predicate 'subsystem == "com.apple.LaunchServices"' --level debug分场景处理
| 场景 | 处理 |
|---|---|
| 开发机自测(ad-hoc 包) | 允许本机运行即可;不要把这个包发给用户 |
| 内部测试分发 | 用 Developer ID 签名 + 公证;或让测试同学在「系统设置 → 隐私与安全性」中手动允许一次 |
| 对外发布 | 签名 → 公证 → stapling → `spctl` accepted;下载页提供 sha256 |
| 用户已下载到“已损坏”包 | 让用户删除后重新下载;同时检查 CDN 是否截断文件(对比 sha256) |
| 企业 MDM 分发 | 用 MDM 推送已签名公证的 pkg,并由 MDM 下发隐私权限(完全磁盘访问等) |
不要用 `xattr -d com.apple.quarantine` 作为发布方案
它只是移除本机隔离标记,用户换机器或重新下载后仍会被拦截,且会绕过系统的安全提示。它只适合本地开发调试。
启动闪退的进一步排查
- 用 `open -a "My Desktop.app" --args --enable-logging` 启动,观察终端输出。
- 在 Console.app 搜索进程名,或 `log show --last 5m --predicate 'process == "My Desktop"'`。
- 确认主进程没有未捕获异常:`process.on("uncaughtException")` 中写日志并退出。
- 检查本地库目录权限:`ls -la "$HOME/Library/Application Support/My Desktop"`。
- 检查服务端可达性:主进程连接失败时应有明确错误码与提示,而不是静默退出。