ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

vibe macOS 分发签名与公证实战:Developer ID、Tauri 集成与 CI/CD 全流程

vibe macOS 分发签名与公证实战:Developer ID、Tauri 集成与 CI/CD 全流程 vibe macOS 分发签名与公证实战Developer ID、Tauri 集成与 CI/CD 全流程【免费下载链接】vibeTranscribe on your own!项目地址: https://gitcode.com/GitHub_Trending/vib/vibe本指南基于 vibe 仓库中的 macOS 签名与公证文档系统讲解如何为基于 Tauri 的 macOS 桌面应用完成 Developer ID Application 证书签名与 Apple 公证Notarization实现 App Store 之外的正常分发。全文覆盖从 CSR 创建、证书链修复、本地tauri build签名、notarytool公证排障到 GitHub Actions 自动化签发的完整链路并以 vibe 仓库中的实际配置tauri.macos.conf.json、entitlements.plist、release.yml作为实现佐证。读完本文你将掌握一套可复现、可排障的 macOS 外部分发签名方案。1. 前置条件与整体流程macOS 外部分发非 App Store要求应用满足两个硬性条件使用 Developer ID Application 证书进行代码签名以及通过 Apple 的 Notarization公证。二者缺一不可——公证是强制性的未公证的 Developer ID 应用会在用户首次运行时被 Gatekeeper 拦截。前提条件已通过 Apple Developer Program 审核年费 99 美元拥有 Apple Developer Account Holder 权限只有 Account Holder 能创建 Developer ID Application 证书一台 macOS 构建机本地签名或 CI 的macos-latestrunner。整体流程可概括为六个阶段下文逐一展开创建证书签名请求CSR在本地 keychain 中生成密钥对在 Apple 开发者后台申请 Developer ID Application 证书安装证书与中间证书确保信任链完整最常见的失败点本地tauri build自动签名 硬化运行时hardened runtime配置 App-Specific Password完成公证与 stapling导出.p12并注入 GitHub Actions Secrets实现 CI 自动签名公证。在 vibe 仓库中桌面端构建产物由tauri build产出见 desktop/src-tauri/tauri.conf.json 中bundle.targets包含dmg、app因此签名与公证贯穿其 macOS 发行流程。2. 创建证书签名请求CSRCSR 是证书申请的起点其本质是在本机生成一对公私钥并把公钥连同身份信息封装成.certSigningRequest文件提交给 Apple。操作步骤在 Mac 上打开钥匙串访问Keychain Access依次进入菜单Keychain Access Certificate Assistant Request a Certificate from a Certificate Authority填写你的电子邮件地址和常用名称Common Name选择Saved to disk保存到磁盘保存生成的.certSigningRequest文件。系统会自动在登录login钥匙串中创建对应的密钥对私钥。这里有两个关键点需要牢记私钥只存在于生成它的这台 Mac。后续步骤 4 安装中间证书、以及从钥匙串导出.p12供 CI 使用都依赖这把私钥因此建议在这台将成为签名母机的机器上完成整个流程必须选择login 钥匙串而非 iCloud 钥匙串否则后续codesign可能无法定位私钥详见第 8 节排障。3. 创建 Developer ID Application 证书登录 Apple 开发者后台的Certificates, Identifiers Profiles证书、标识符与描述文件页面点击Create a Certificate 按钮选择Developer ID Application选择G2 Sub-CA推荐上传第 2 节生成的 CSR 文件下载生成的.cer证书文件。注意只有 Apple Developer Account Holder 可以创建 Developer ID Application 证书。团队中的其他成员无法代劳这是权限模型的设计不是配置错误。选择 G2 Sub-CA 意味着证书链的根是Apple Root CA - G2中间证书是Developer ID Certification Authority (G2)。这一步选择直接决定了第 4 节需要安装哪些中间证书。4. 安装证书与中间证书最容易踩坑的一步4.1 安装 Developer ID 证书双击下载的.cer文件安装到login钥匙串不要安装到 iCloud。安装完成后在钥匙串访问中展开My Certificates确认证书条目下有可展开的私钥箭头——这一步验证证书与私钥正确关联。4.2 安装中间证书完成信任链关键G2 Sub-CA 需要 Apple 中间证书才能构成完整信任链而 macOS 并不总是预装它。这是文档明确标注为 critical 的原因也是现实中最高频的签名失败根因。缺少中间证书的典型症状执行security find-identity -p codesigning时显示1 matching identity 0 valid identities表面看像是 ACL/权限问题实际上几乎总是证书链断裂。修复方法前往 Apple Certificate Authority 页面下载两个证书Developer ID - G2有效期至 09/17/2031Apple Root CA - G2如果系统根证书中尚未安装双击每个文件安装到login钥匙串在钥匙串访问中逐一检查两个证书确认信任设置均为Use System Defaults使用系统默认不要手动覆盖。4.3 验证信任链在钥匙串访问中打开 Developer ID Application 证书信任链应呈现如下结构Apple Root CA - G2 └── Developer ID Certification Authority (G2) └── Developer ID Application: Your Name (TEAMID)链条中任何一环显示红色 X 都代表信任链断裂需要回到 4.2 重新安装。4.4 验证签名身份security find-identity -v -p codesigning预期输出1 valid identity found如果仍显示 0 valid identities参见第 8 节排障。5. 本地签名接入 Tauri 构建Tauri 对 macOS 签名的支持是开箱即用的只要告诉它签名身份signing identitytauri build会自动完成二进制签名、硬化运行时注入与应用打包。5.1 配置签名身份在tauri.conf.json的bundle.macOS中指定签名身份{ bundle: { macOS: { signingIdentity: Developer ID Application: Your Name (TEAMID) } } }或者通过环境变量注入适合 CI避免把身份写死在配置里export APPLE_SIGNING_IDENTITYDeveloper ID Application: Your Name (TEAMID)5.2 vibe 的实际 macOS 打包配置在 vibe 仓库中macOS 相关的打包配置独立存放在 desktop/src-tauri/tauri.macos.conf.json其中hardenedRuntime被显式开启并引用了entitlements.plist{ bundle: { externalBin: [binaries/vibe-server, binaries/ffmpeg], macOS: { entitlements: entitlements.plist, hardenedRuntime: true, dmg: { background: ../../design/dmg_background.png, appPosition: { x: 145, y: 130 }, applicationFolderPosition: { x: 560, y: 130 }, windowSize: { height: 340, width: 720 } } } } }这里有两个值得注意的工程细节sidecar 也会被签名vibe-server转录引擎与ffmpeg作为 external binaries 打包进.appTauri 会用同一份 entitlements 对它们重新签名保证整个 bundle 内所有二进制统一受 hardened runtime 约束DMG 布局已定制dmg_background.png、app 图标位置145,130与应用文件夹位置560,130、窗口尺寸720×340都在仓库的 design/dmg_background.png 及配置中预先定义。5.3 entitlements最小化硬化运行时权限硬化运行时hardened runtime会默认阻止大量危险操作任何额外能力都需要通过 entitlements 显式授予。vibe 的 desktop/src-tauri/entitlements.plist 中只保留了三项注释里详细说明了取舍逻辑keycom.apple.security.device.audio-input/key true/ keycom.apple.security.network.client/key true/ keycom.apple.security.cs.allow-jit/key true/com.apple.security.device.audio-input麦克风访问vibe 需要录音与 desktop/src-tauri/Info.plist 中的NSMicrophoneUsageDescription配套使用com.apple.security.network.client出站网络模型下载、更新检查、分析上报com.apple.security.cs.allow-jit为vibe-serversidecar 的 GPU 路径预留的 MAP_JIT 许可——该 sidecar 将 ggml Metal 内核以源码形式内嵌模型加载时由驱动在进程内编译 pipeline是唯一可能触发 W^X 强制的环节。entitlements 文件的注释还明确强调了两项刻意不加的能力及其理由不加disable-library-validationbundle 内无第三方 dylib加了反而允许注入任意团队 dylib、不加allow-unsigned-executable-memory范围远大于 allow-jit且无任何组件需要可写可执行内存。这体现了每个 entitlement 都是硬化运行时的一个漏洞的安全意识值得其他项目借鉴。5.4 执行构建并验证签名tauri buildTauri 会自动完成以下工作用codesign对全部二进制签名应用硬化运行时生成签名后的.app与 DMG。验证签名是否生效codesign --verify --deep --strict /path/to/YourApp.app spctl --assess --type exec /path/to/YourApp.appcodesign --verify --deep --strict深度、严格校验 bundle 内所有签名spctl --assess --type exec模拟 Gatekeeper 评估此时尚未公证若提示未通过属于预期公证完成后会通过。vibe 的整体构建流程可参考 docs/building.md仓库使用chore任务编排chore build先拉取 sidecar 再执行生产构建macOS 上chore upgrade还会把新构建替换到/Applications/vibe.app并重新启动。6. 公证Notarization公证是 Developer ID Application 证书的强制要求。Tauri 会自动完成提交、轮询和 stapling订书钉三个环节但仍需你准备凭据并了解手动排障手段。6.1 生成 App-Specific PasswordApple 不接受普通 Apple ID 密码用于公证否则 Notarization 401 错误会如期而至。正确姿势登录 appleid.apple.com进入Sign-In and Security App-Specific Passwords生成一个新密码并妥善保存。6.2 设置环境变量export APPLE_IDyouremail.com export APPLE_PASSWORDapp-specific-password export APPLE_TEAM_IDTEAMIDTeam ID 可以从签名身份里取——执行security find-identity -v -p codesigning输出中括号内的 10 位字符即为 Team IDsecurity find-identity -v -p codesigning # Look for the 10-character code in parentheses: (TEAMID)设置完成后再次运行tauri buildTauri 将依次执行把应用提交给 Apple 进行公证等待 Apple 返回结果将公证票据 stapling订书钉到应用上。6.3 公证可能很慢如何安全中断并手动查状态首次对新应用/新证书做公证可能耗时数小时payload 越大越明显这属于正常现象。文档给出了一个重要技巧上传提交完成后可以安全地CtrlC中断 Tauri 构建——此时公证完全在 Apple 服务器端进行本地中断不影响结果。中断后用notarytool手动查询进度xcrun notarytool history \ --apple-id $APPLE_ID \ --password $APPLE_PASSWORD \ --team-id $APPLE_TEAM_ID当状态从 In Progress 变为终态后可查看详细日志日志仅在 Apple 处理完成后才可获取In Progress 期间无法读取xcrun notarytool log submission-id \ --apple-id $APPLE_ID \ --password $APPLE_PASSWORD \ --team-id $APPLE_TEAM_ID日志中会给出详细的处理结果若被拒绝也会明确列出拒绝原因。超时兜底如果公证卡在 In Progress 超过 12 小时建议联系 Apple Developer Support——某些情况下需要 Apple 在后台手动配置团队的公证能力。6.4 状态为 Accepted 后手动 stapling若中断了构建公证通过后需要手动补 staplingxcrun stapler staple /path/to/vibe.appStapling 是按.appbundle 粒度进行的——一条票据覆盖 bundle 内所有二进制无需对单个二进制分别操作。公证通过后的后续提交会明显加快。7. CI/CD 自动化GitHub Actions 集成把签名与公证搬进 CI核心是把母机钥匙串中的证书私钥安全地搬运到 runner再以 Secrets 形式注入 Tauri 环境。7.1 导出证书为 .p12打开钥匙串访问 登录钥匙串 My Certificates找到你的 Developer ID Application 证书右键证书 Export导出以.p12格式保存并设置一个强密码。7.2 Base64 编码openssl base64 -A -in /path/to/certificate.p12 -out certificate-base64.txt-A参数确保输出为单行 Base64方便作为单个 Secret 值粘贴。7.3 设置 GitHub Actions Secrets下表是 vibe 的 macOS 签名所需的全部 SecretsSecretValueAPPLE_CERTIFICATEContents ofcertificate-base64.txtAPPLE_CERTIFICATE_PASSWORDThe.p12export passwordAPPLE_SIGNING_IDENTITYDeveloper ID Application: Your Name (TEAMID)APPLE_IDYour Apple ID emailAPPLE_PASSWORDApp-specific password (not your Apple ID password)APPLE_TEAM_IDYour 10-character team ID通过 CLI 设置gh secret set默认作用于当前目录对应的仓库。先确认目标仓库gh repo view --json nameWithOwner -q .nameWithOwner再逐个写入gh secret set APPLE_CERTIFICATE -b contents of certificate-base64.txt gh secret set APPLE_CERTIFICATE_PASSWORD -b your-p12-password gh secret set APPLE_SIGNING_IDENTITY -b Developer ID Application: Your Name (TEAMID) gh secret set APPLE_ID -b youremail.com gh secret set APPLE_PASSWORD -b your-app-specific-password gh secret set APPLE_TEAM_ID -b TEAMID7.4 清理本地敏感文件设置完成后立即删除本地的证书与编码文件rm certificate.p12 certificate-base64.txt7.5 在 release 工作流中的实际落地vibe 的 .github/workflows/release.yml 展示了完整做法手动触发开关工作流提供sign-macos布尔输入默认false只有显式勾选才会注入签名环境避免日常构建触发 Apple 公证队列矩阵双架构macos-latestrunner 同时构建aarch64-apple-darwinApple Silicon与x86_64-apple-darwinIntel两个目标环境注入将 Secrets 写入$GITHUB_ENV供tauri-action读取- name: Setup macOS signing env if: matrix.platform macos-latest inputs.sign-macos run: | echo APPLE_CERTIFICATE${{ secrets.APPLE_CERTIFICATE }} $GITHUB_ENV echo APPLE_CERTIFICATE_PASSWORD${{ secrets.APPLE_CERTIFICATE_PASSWORD }} $GITHUB_ENV echo APPLE_SIGNING_IDENTITY${{ secrets.APPLE_SIGNING_IDENTITY }} $GITHUB_ENV echo APPLE_ID${{ secrets.APPLE_ID }} $GITHUB_ENV echo APPLE_PASSWORD${{ secrets.APPLE_PASSWORD }} $GITHUB_ENV echo APPLE_TEAM_ID${{ secrets.APPLE_TEAM_ID }} $GITHUB_ENV发布前置校验构建前会从tauri.conf.json读取版本号并强制要求存在对应的website/changelog/version.md发布说明缺失即中止自动更新签名Tauri Updater 相关的TAURI_SIGNING_PRIVATE_KEY与TAURI_SIGNING_PRIVATE_KEY_PASSWORD也在此注入更新包同样需要签名。由此tauri-action在 CI 中自动完成解码.p12、导入钥匙串、签名、公证与 stapling 全流程产出的.app/.dmg可直接对外分发。仓库同时提供 Windows 侧的 YubiKey 远程签名方案docs/code-signing/windows_yubikey.md 与 scripts/sign.py与 macOS 侧形成完整的跨平台签名矩阵。8. 故障排查Troubleshooting1 matching identity, 0 valid identities原因缺少中间证书Apple Developer ID G2。修复从 Apple Certificate Authority 下载并安装中间证书参见第 4 节。这是最常见的问题表象像 ACL/权限异常但几乎总是证书链断裂。其他常规检查项确认各证书的信任设置为Use System Defaults而非手动覆盖确认私钥在login钥匙串而非 iCloud重置钥匙串访问控制列表ACLsecurity set-key-partition-list -S apple-tool:,apple:,codesign: -s -k PASSWORD ~/Library/Keychains/login.keychain-db重启securityd守护进程sudo killall securitydinternal error in Code Signing subsystem通常与 0 valid identities 同根同源——先修复信任链此错误大概率随之消失。Notarization 401 错误原因使用了普通 Apple ID 密码而非 App-Specific Password。修复在 appleid.apple.com 生成 App-Specific Password参见第 6.1 节。证书不出现在 My Certificates证书未与钥匙串中的私钥正确关联。需要回到生成私钥的那台 Mac重新创建 CSR 并走完证书申请流程——私钥与证书的配对关系无法在另一台机器上凭空重建。9. 关键要点回顾信任链优先绝大多数签名失败都是中间证书缺失导致先security find-identity -v -p codesigning验证再谈其他最小化 entitlementsvibe 的 entitlements.plist 只保留三项能力每个多余 entitlement 都是硬化运行时的攻击面公证凭据必须是 App-Specific PasswordTeam ID 从签名身份中提取公证可中断上传提交后本地 CtrlC 不影响结果用notarytool history/log手动跟进CI 自动化.p12导出 → Base64 → Secrets 注入配合 release 工作流的sign-macos开关实现按需的签名公证发布。【免费下载链接】vibeTranscribe on your own!项目地址: https://gitcode.com/GitHub_Trending/vib/vibe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表