00 / 00

macOS 签名与权限

桌面应用在 macOS 上处理代码签名、Apple Developer 注册、TCC 权限和 Tauri 配置的完整流程

macOS 桌面开发里,最容易让人踩坑的是”权限授权”。麦克风、输入监听、辅助功能、自动粘贴这些能力,不只看应用名字,还看 bundle identifier、代码签名、安装路径和最终的 app bundle。开发时频繁重建、换路径、换签名方式,就可能每次都要重新授权。

这篇以 Tauri 为例,但 Electron 也适用同一套 macOS 规则。

如果你还没有理解 Apple Developer Program、Bundle ID、App ID、证书和描述文件的关系,先看 Apple 平台配置

先搞清你碰到的是哪类权限

macOS 隐私权限由 TCC 管理。常见能力对应的权限大致如下:

能力常见触发方式可能涉及的系统权限
录音getUserMedia、原生录音 APIMicrophone
全局快捷键快捷键插件、系统事件监听Accessibility 或 Input Monitoring
监听修饰键CGEventTapCreate、低层键盘事件Input Monitoring,部分场景还会碰到 Accessibility
自动粘贴到当前应用AppleScript、System Events、模拟键盘Automation 和 Accessibility
截屏或屏幕识别截图 API、窗口捕获Screen Recording

命令行能做的是重置这些记录,让系统下一次重新弹窗:

tccutil reset Microphone com.example.desktop
tccutil reset Accessibility com.example.desktop
tccutil reset ListenEvent com.example.desktop
tccutil reset AppleEvents com.example.desktop

别把 reset 当日常流程。它会清掉已有授权,只适合处理旧 bundle id、旧签名、误点拒绝或系统设置里残留脏记录。

为什么开发包会反复要权限

TCC 不是只按应用显示名保存授权。下面这些变化都会让 macOS 重新判断应用身份:

  • CFBundleIdentifier 变了,比如从 com.example.app 改成 com.example.desktop
  • .app 路径变了,比如从 target/release/bundle/macos 换到 /Applications
  • 代码签名变了,比如每次都是 ad-hoc 签名或签名 hash 变化明显
  • Info.plist 没有被签名封存,系统无法把 bundle 信息稳定绑定到签名
  • dev、preview、release 共用一个 bundle id,权限记录互相污染

可以先用这两个命令看现状:

security find-identity -v -p codesigning
codesign -dv --verbose=4 path/to/MyApp.app

重点看:

  • Identifier 是否和 Info.plist 里的 CFBundleIdentifier 一致
  • Signature 是否是 adhoc
  • 有没有 TeamIdentifier
  • Info.plist 是否显示为 not bound

如果 security find-identity 显示 0 valid identities found,说明钥匙串里还没有可用的代码签名身份。

免费 Apple Account 和付费 Developer Program 的区别

只做学习和本机开发,可以先用免费 Apple Account。Apple 官方说了,没加入 Apple Developer Program 的账号也能配合 Xcode 做个人开发测试(Xcode 里的 Personal Team)。

Certificates, Identifiers & Profiles 这些开发者后台资源通常要求加入 Apple Developer Program。如果你访问证书页面看到:

Access Unavailable
This resource is only for developers enrolled in a developer program or members of an organization’s team in a developer program.

意思很直接:当前 Apple Account 没有这个资源的访问权,或者没切到有权限的团队。免费账号主要用于 Xcode Personal Team 自动管理;如果要在 Apple Developer 网页后台走 CSR 上传、证书下载、Tauri 手工签名这条路,就得注册 Apple Developer Program,或让已有团队把你加为成员并给相应权限。

怎么选

目标推荐账号/证书说明
本机调试,暂时不分发Xcode Personal Team 或本机自签名可降低开发摩擦,但能力有限
Tauri 手工签名开发包Apple Development适合稳定本机开发身份;网页后台创建通常需要 Program 权限
发给别人下载使用Developer ID Application + notarization需要 Apple Developer Program
上架 Mac App StoreMac App Distribution需要 Apple Developer Program

Tauri 官方也写了,macOS 签名可以用付费或免费 Apple Developer account;免费账号只能测试和开发,不能公证应用,打开时仍会显示未验证提示。正式分发要走 Developer ID 和 notarization。

注册 Apple Developer Program

注册入口:

Apple Developer Program Enrollment

个人开发者通常选 Individual。准备好:

  • Apple Account,并开启双因素认证
  • 合法姓名,Apple 会用它签署协议;个人账号的 App Store seller name 也会显示这个姓名
  • 邮箱、电话、地址等联系信息
  • 付款方式;Apple Developer Program 年费通常是 99 USD 或当地等值价格

如果用公司主体注册 Organization,还需要:

  • 公司法定实体信息
  • D-U-N-S Number
  • 有权代表公司签约的人完成注册

注册完成后,再回 Certificates, Identifiers & Profiles 页面创建证书。如果你加入了多个团队,先在页面右上角切到正确团队。

创建 CSR

CSR 就是 Certificate Signing Request。Apple 需要它来给你的公钥签发证书,私钥留在本机钥匙串里。

推荐用 Keychain Access:

  1. 打开 Keychain Access
  2. 菜单选择 Certificate Assistant > Request a Certificate From a Certificate Authority
  3. 填邮箱和常用名称
  4. 选择 Saved to disk
  5. 保存为 CertificateSigningRequest.certSigningRequest

也可以用命令行生成:

mkdir -p ~/Downloads/myapp-apple-signing
certtool r ~/Downloads/myapp-apple-signing/CertificateSigningRequest.certSigningRequest a
certtool V ~/Downloads/myapp-apple-signing/CertificateSigningRequest.certSigningRequest

certtool 是交互式命令。用途选 s,签名算法选 2,也就是 RSA with SHA256。Common Name 和 Email Address 填你自己的信息。

创建并安装 Apple Development 证书

进入 Apple Developer 后台:

  1. 打开 Certificates, Identifiers & Profiles
  2. 新建 Certificate
  3. 开发阶段选择 Apple Development
  4. 上传刚才生成的 CSR
  5. 下载 .cer 文件
  6. 双击 .cer,或用命令导入 login keychain
security import ~/Downloads/development.cer -k ~/Library/Keychains/login.keychain-db
security find-identity -v -p codesigning

成功后会看到类似:

Apple Development: Your Name (TEAMID)

如果看不到,一般是证书和本机私钥没配对。确认 CSR 是这台机器生成的,且证书装到了 login keychain。

配置 Tauri 使用签名身份

Tauri 可以通过 tauri.conf.json 或环境变量指定签名身份。

{
  "bundle": {
    "macOS": {
      "signingIdentity": "Apple Development: Your Name (TEAMID)",
      "entitlements": "Entitlements.plist"
    }
  }
}

也可以临时用环境变量:

APPLE_SIGNING_IDENTITY="Apple Development: Your Name (TEAMID)" vp run --filter @myapp/desktop tauri:build

如果只是做 Apple Silicon 本机 ad-hoc 签名,可以设成 -

{
  "bundle": {
    "macOS": {
      "signingIdentity": "-"
    }
  }
}

ad-hoc 签名只能解决”有签名”这个最低要求,不能让用户跳过 Gatekeeper,也不能公证。要稳定权限和正式分发时,别长期依赖它。

固定开发身份

开发阶段建议 dev 和 release 分开:

devrelease
Bundle IDcom.example.app.devcom.example.app
App 名称Example DevExample
安装路径/Applications/Example Dev.app/Applications/Example.app
签名Apple DevelopmentDeveloper ID Application

这样做有两个好处:

  • dev 权限重置不影响正式版用户
  • macOS 更容易持续识别同一个开发应用

重新授权时的建议顺序

如果你改过 bundle id 或签名方式,按这个顺序清理一次:

  1. 退出应用
  2. 删除旧开发包,保留一个固定路径
  3. 用新签名重新构建
  4. 必要时重置旧 TCC 记录
  5. 启动应用,让系统弹出权限请求
  6. 在系统设置里手动打开 Accessibility、Input Monitoring、Microphone 等权限

命令示例:

tccutil reset All com.example.desktop.dev
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
open "x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"

macOS 不允许普通命令行脚本直接替用户授予隐私权限。企业设备可以用 MDM/PPPC profile 管控部分权限,个人开发机一般不走这条路。

正式分发还需要 Developer ID 和公证

Apple Development 适合开发。你要把 DMG、ZIP 或 .app 发给用户下载,就需要:

  • Developer ID Application 证书
  • Tauri 构建时使用这个证书签名
  • 提交 notarization
  • stapler 把公证票据绑定到应用或 DMG

这一步需要 Apple Developer Program。免费账号不能完成 notarization。

公证凭据怎么准备

Developer ID 签名和 notarization 是两步。正式分发时,安装包要先用 Developer ID Application 签名,再提交 Apple 公证。Tauri 可以在构建或打包时读取下面这些环境变量。

目标常见变量说明
指定签名身份APPLE_SIGNING_IDENTITY覆盖 tauri.conf.json 里的 signing identity
CI 导入证书APPLE_CERTIFICATEAPPLE_CERTIFICATE_PASSWORD.p12 证书放进 CI secret
App Store Connect API 公证APPLE_API_ISSUERAPPLE_API_KEYAPPLE_API_KEY_PATH推荐给 CI 使用,避免 Apple ID 交互
Apple ID 公证APPLE_IDAPPLE_PASSWORDAPPLE_TEAM_IDAPPLE_PASSWORD 应使用 app-specific password

如果构建产物只显示已签名,但 Gatekeeper 仍提示来源无法验证,通常是公证或 stapling 没完成。先检查 Tauri build 输出,再用干净机器安装验证。

发布前验收

  • security find-identity -v -p codesigning 能看到目标证书
  • .app 的 identifier、TeamIdentifier 和预期一致
  • 产物使用 Developer ID Application 签名
  • notarization 通过,并且 DMG 或 app 已 staple
  • 在非开发机上安装打开,不需要用户手动绕过 Gatekeeper
  • 需要麦克风、输入监听、辅助功能等权限时,弹窗和系统设置入口都能正常工作

参考资料

这篇文档有问题?