entitlements.plist 是一个用于声明应用或二进制在运行时需要哪些“特权权限” 的配置文件。
这些权限包括但不限于:
1、是否启用 App Sandbox(应用沙盒,macOS App Store 必须要求);
2、是否允许访问网络、文件、打印机、USB、iCloud、摄像头、麦克风等;
3、是否支持应用组(App Group)共享数据;
4、是否启用硬件加速、JIT、系统扩展等高级功能。
可以理解为向系统申请的“运行许可证清单”,没有申请(加入对应entitlement)的功能,即使调用API,系统也会限制使用。
常见示例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- 启用沙盒,App Store 必须 -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- 允许网络访问 -->
<key>com.apple.security.network.client</key>
<true/>
<!-- 允许文件读取用户选中的文件 -->
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>
创建entitlements.plist文件
在Xcode中右键选择“New File from Template…”:

选择Property List:

命名为entitlements.plist或其他名称。

使用场景
1、开发一个 macOS App(上架 App Store):必须使用entitlements.plist,需要沙盒、网络、读写文件权限。
2、给一个工具/CLI 程序加签:推荐使用entitlements.plist,例如pngquant、helper。
3、App 使用 iCloud:必须使用entitlements.plist,例如<key>com.apple.iCloud…。
4、App 使用 App Groups:必须使用entitlements.plist,多进程共享数据。
使用示例
1、使用entitlements.plist给可执行文件授权
App Store 要求:所有可执行文件都必须启用沙盒(App Sandbox)权限,即必须为可执行文件添加com.apple.security.app-sandbox。
但是com.apple.security.app-sandbox权限会让可执行文件变成独立的沙盒,所以还需要额外配置com.apple.security.inherit,让可执行文件能够继承主应用的权限:
所以,在创建的entitlements.plist文件中配置以下字段:
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>

使用终端签名可执行文件,加入 –entitlements 参数:
codesign --force --options runtime \
--entitlements "/path/to/entitlements.plist" \
--sign "Developer ID Application: xxx" \
"/path/to/可执行文件路径"
entitlements.plist和可执行文件都是绝对路径,Developer ID Application证书也已申请的证书名称对应。
签名完成后,终端输出:
/path/to/pngquant: replacing existing signature
表示codesign替换了原来的签名,成功写入了新指定的签名和权限(entitlements)。
使用codesign验证签名是否成功:
codesign -dvvv --entitlements - "/path/to/pngquant"
终端输出:
Executable=/Users/fangjunyu.com/Documents/Apple开发/Mac应用-轻压图片/ImageSlim/ImageSlim/Packages/pngquant
Identifier=pngquant
Format=Mach-O universal (x86_64 arm64)
...
有输出,则表示签名成功,如果没有输出,则表示没有签名成功。
entitlements.plist和Info.plist、项目名.entitlements有什么区别?
在实际项目中,创建entitlements.plist文件,还有Info.plist和项目名.entitlements文件,这三个文件的格式相同。

1、Info.plist 是应用的“描述文件”
描述应用本身的元信息,包括 App 名称、版本、图标、启动文件、权限请求提示等。

特点:必须包含在 .app 包中(Contents/Info.plist),通常由Xcode 会自动生成和管理(也可以手动创建),与 App Store Connect 上传有关,不能用于声明“沙盒权限”等执行行为。
2、entitlements.plist / 项目名.entitlements 是“沙盒和权限声明文件”
定义应用或二进制的执行权限,如是否启用 App Sandbox、是否访问文件、网络、iCloud 等功能。

特点:
1、用于签名时使用:通过 codesign –entitlements xxx.plist 引用;
2、控制是否启用沙盒:App Store 必须启用 com.apple.security.app-sandbox;
3、适用于主应用、Helper、工具程序:每个可执行文件都需要独立加上 Entitlements(如果要沙盒);
4、文件名自由:entitlements.plist、项目名.entitlements、Helper.entitlements 等都行,只要签名时指定就可以。
3、三者区别
1、Info.plist 是每个 .app 必有的;
2、项目名.entitlements 是在 Xcode 项目中配置沙盒、网络权限等时自动生成的,在 Xcode 构建主应用时会自动使用;
3、entitlements.plist 是自己手动创建的,用于给外部工具(如 pngquant)单独签名时使用,文件名无要求,只要在 codesign 命令中正确传入即可。
项目名.entitlements 和 entitlements.plist 是一样的吗?
两者格式完全一样,作用也一样,唯一的区别是:
1、项目名.entitlements:Xcode 默认用于主 App 的 Entitlements,可以用来签名二进制文件。
2、entitlements.plist,常见用于手动签名 CLI 工具,完全通用。
如果项目中有项目名.entitlements,可以直接在项目名.entitlements文件中添加沙盒权限,并使用codesign给二进制文件签名:
codesign --force --options runtime --entitlements path/to/项目名.entitlements --sign "Developer ID Application: ..." /path/to/pngquant
注意事项:
1、二进制文件通常使用的是 CLI 方式签名,手动指定的 entitlements;
2、项目名.app 使用的是 Xcode 构建自动签名,项目名.entitlements 是通过项目设置引用的;
3、虽然文件内容可以共用,但路径引用和作用机制不同。
推荐方案:
如果认为清晰结构很重要,推荐:
主 App 用 项目名.entitlements;
给外部工具(如 pngquant)创建单独的 entitlements.plist,只包含:
<key>com.apple.security.app-sandbox</key>
<true/>

这样逻辑清晰、好维护,防止混乱。
总结
外部工具需要签名时,通常建议给外部工具单独创建entitlements.plist文件并配置相关权限,然后使用codesign给外部工具签名。
如果不想要创建entitlements.plist文件,也可以使用系统自动创建的项目名.entitlements。
此外,.entitlements 与 .plist 文件本质是同一种东西:它们其实都遵循 Apple 的 Property List 规范。区别在于:
1、Xcode 内部保存的 项目名.entitlements,的是 binary plist 或 IDE 优化结构(以支持可视化编辑)
2、手动创建的 entitlements.plis,是 XML 格式(纯文本)。
本质一样,系统在签名验证时并不区分格式。
甚至可以在终端用 plutil 相互转换:
plutil -convert xml1 ImageSlim.entitlements
plutil -convert binary1 entitlements.plist
最后,讲一下两个plist文件的区别:
Info.plist和entitlements.plist文件虽然都是.plist文件,格式也相同,但是两者的作用和使用场景完全不一样。
Info.plist用于描述应用的信息,在App启动时,被系统自动读取,必须在.app/Contents/Info.plist路径下,用户和系统都可以看到。
entitlements.plist文件是用于声明应用或可执行文件的运行权限,被codesign读取附加到签名中,用于App被签名/校验时,系统检查权限等场景,用户不可见,只在签名和权限校验时使用。
虽然结构、格式一致,但是因为它们的作用不同,所以必须分开创建和使用。
如果把entitlements.plist的权限写入Info.plist,就会产生以下问题:
1、.app包中的Info.plist是公开的,容易被伪造/拷贝;
2、entitlements.plist权限需要通过签名写入可执行文件,无法在Info.plist文件中实现签名;
3、App Store 和 macOS 系统内部流程要求严格区分 metadata(元数据)和 entitlement(权限边界);
4、多个二进制可执行文件(主程序、helper、XPC、CLI)可能共用同一个 Info.plist,但各自需要不同的 entitlements权限。
虽然 entitlements.plist 和 Info.plist 文件结构一样,但它们分别服务于“系统识别你是谁”和“系统允许你做什么”这两个不同机制,必须分开使用、不能混用。
相关文章
1、How to sandbox a command line tool?:https://stackoverflow.com/questions/12959958/how-to-sandbox-a-command-line-tool
2、Xcode项目Info.plist文件位置:https://fangjunyu.com/2024/12/08/xcode%e9%a1%b9%e7%9b%aeinfo-plist%e6%96%87%e4%bb%b6%e4%bd%8d%e7%bd%ae/
3、Apple Developer证书:https://fangjunyu.com/2025/07/06/apple-developer%e8%af%81%e4%b9%a6/
4、Xcode报错:”pngquant” must be rebuilt with support for the Hardened Runtime. Enable the Hardened Runtime capability in the project editor:https://fangjunyu.com/2025/07/14/xcode%e6%8a%a5%e9%94%99%ef%bc%9apngquant-must-be-rebuilt-with-support-for-the-hardened-runtime-enable-the-hardened-runtime-capability-in-the-project-editor/
5、Apple Property List规范:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/PropertyLists/Introduction/Introduction.html