2026 年 Mac 云 CI 里做 Apple 公证(Notarization):notarytool 凭据、常见拒绝项与「无头 SSH vs 短时桌面会话」分流决策表
很多团队已经能在 Mac 云节点上稳定 xcodebuild archive,却卡在「公证」这一步:要么 notarytool 报凭据错误,要么 Apple 返回难以解读的拒绝详情,要么流水线必须突然接入图形会话。本文给出一套可写进 Runbook 的分流方法:先用对照表归类失败,再用决策矩阵判断纯 SSH 是否足够,最后给出 notarytool 提交、轮询、stapler 与日志保留的五步落地顺序,并附 Mac 云侧磁盘与并发建议。
本文要点
1. 痛点拆解:公证与上传、签名混为一谈
在 Mac 云或自托管 Runner 上,常把三条链路捆在一起:代码签名、Apple 公证(Notarization)、App Store Connect / TestFlight 上传。相关但凭证与失败语义不同。
- 签名:Profile、证书链与 Hardened Runtime 决定
codesign;失败多在 Archive/export,日志在xcodebuild。 - 公证:向 Apple 提交 zip/dmg/pkg 等待检物;拒绝多在 notarytool 的 JSON 或
log输出,而非本地编译器。 - 上传:Transporter/Fastlane 等走 App Store Connect API Key;与公证端点不同,混用 Secrets 会失去分层排障。
三层拆开,是在 Mac 云「像管 VPS 一样 SSH」前提下稳定自动化的关键。
2. CI 公证失败类型对照表
用于快速定位:先查签名/entitlements,还是先查 notarytool 与网络。
| 现象 | 更可能根因 | 优先动作 |
|---|---|---|
notarytool 立即报认证失败 | App Store Connect API Key 与公证用途不匹配、Key 过期、Issuer ID 填错 | 核对 Key 权限、.p8 路径、CI 机密注入是否截断换行 |
提交成功但长时间 In Progress | Apple 侧队列、包体过大、或扫描命中额外启发式 | 保留 submission id,使用 notarytool log 拉取详情;对大包体设置更长超时 |
| 拒绝信息指向 hardened runtime / library validation | 嵌入二进制未签名、使用了不当的 disable-library-validation、或 Helper 未独立签名 | 对 app bundle 做 codesign --verify --deep 与 entitlements diff |
| 仅 CI 失败、本机图形会话成功 | 钥匙串或交互依赖 | 见第三节矩阵:短时 VNC 或拆分人工一步 |
3. 无头 SSH 与短时桌面会话:决策矩阵
Mac 云可像 Linux 一样管 launchd/SSH;公证偶发需图形或钥匙串解锁,下表作工程分流(安全边界由团队自定)。
| 维度 | 纯 SSH 无头(推荐默认) | 短时桌面 / VNC 会话 |
|---|---|---|
| 凭据形态 | 使用 API Key + notarytool 非交互参数;Secrets 只注入到 CI Job 环境 | 需要钥匙串解锁、系统弹窗或仅 GUI 工具才能完成的步骤 |
| 可审计性 | 日志可完整落盘到构建目录并随制品归档 | 人工步骤多,需额外录屏或双人复核才能满足审计 |
| 稳定性 | 适合 7×24 重复执行与多分支并行 | 适合低频、关键路径上的例外流程,不建议作为默认路径 |
| 与 Mac 云的结合方式 | launchd 固定 PATH,CI 用户与 Xcode 命令行工具版本钉死 | 为公证子任务单独队列,避免与重负载 xcodebuild 争用 CPU 与磁盘 |
4. 五步落地:notarytool → 轮询 → staple → 归档 → 回滚
2026 年仍可复用的最小顺序;flag 以本机 xcrun notarytool 帮助为准。
- 冻结工具链:镜像记录
xcodebuild -version,CI 显式锁定,避免静默升级致行为漂移。 - 准备提交物:dmg/zip/pkg 记 sha256;路径在构建目录内且 CI 用户可读;大包预留临时空间。
- submit:API Key 调用
notarytool submit,stdout/JSON 写入artifacts/notary/submit.log。 - 轮询:
notarytool info等轮询,队列高峰指数退避;失败用notarytool log拉详情并随制品上传。 - staple 与回滚:对 dmg/pkg 执行
xcrun stapler staple;日志与包一并归档;staple 失败则阻断发布并保留上一版制品。
示意(请替换 Key 与路径):
5. 可引用参数:超时、磁盘与并发
供容量评审与 Runbook;以 Apple 文档与合规为准。
- 磁盘:公证伴随解包压缩;在已有 Archive 外建议约 25GB 峰值缓冲;低于约 10GB 应拒新 Job 或清
DerivedData/旧ipa。 - 轮询:拆分「已提交」与「已公证」指标;单 submission 上限约 45–90 分钟并按包体分层。
- 并发:同机多 notary 易抢 IO;公证并发建议 1–2,与重编译错峰。
- 日志与密钥:notary JSON/log 建议保留约 90 天;与上传日志分库。公证 Key 与上传 Key 分离并按约 90 天轮换。
6. FAQ 与和 TestFlight 链路的衔接
问:公证和 TestFlight 上传哪个先做? 常见是先签名与公证/staple,再上传;顺序须与 export 形态一致并写进 Runbook,避免 Gatekeeper 与渠道状态不一致。
问:CI 里 notarytool 偶发网络错误? 查代理 HTTPS_PROXY/NO_PROXY;公证与上传域名可能不同。
问:能否完全避免 VNC? 多数可以;若遇钥匙串/图形依赖,优先拆分密钥与单步人工,而非长期桌面共享。
笔记本易受关机与策略影响;纯托管分钟 Runner 大包公证成本高。要稳定 Apple 工具链与可审计 Key、少扛硬件运维时,专用 Mac 云更适合「签名—公证—上传」;可结合站内 TestFlight 文对齐 Job 与 Secrets。