需利用macOS用户权限模型与沙盒机制实现应用隔离:一、将应用安装至各用户~/Applications并清除隔离属性;二、启用App Sandbox并验证其运行状态;三、通过用户级Launch Services数据库隔离文件类型关联;四、辅助功能等隐私权限按账户独立授权;五、使用launchd用户代理实现服务级隔离。

如果您在macOS系统中为不同用户账户安装应用,但希望这些应用彼此隔离、互不干扰,则需要利用系统内置的用户权限模型与沙盒机制。以下是实现应用隔离的具体技术细节:
一、利用用户主目录的独立性
macOS为每个用户账户分配独立的主目录(如 /Users/username),其下的 Applications、Library、Downloads 等子目录默认仅对该用户可读写。将应用安装至各自用户的 ~/Applications 目录,可天然避免跨账户访问。
1、以目标用户身份登录系统,确保当前 shell 环境归属该用户。
2、在 Finder 中前往“前往”菜单,按住 Option 键后选择“资源库”,进入当前用户的 ~/Library 目录。
3、在用户主目录下手动创建 Applications 文件夹(若不存在):mkdir -p ~/Applications。
4、将应用包(.app)拖入该 ~/Applications 文件夹,而非全局 /Applications。
5、通过终端执行 xattr -d com.apple.quarantine ~/Applications/AppName.app 清除隔离属性,确保首次启动不被阻止。
二、启用应用沙盒(App Sandbox)并配置权限范围
对于从 Mac App Store 安装或经开发者签名启用沙盒的应用,系统强制其运行在受限环境中,无法直接访问其他用户的文件、进程或偏好设置。沙盒策略由 entitlements.plist 控制,限制包括文件系统路径、网络通信、辅助工具调用等。
1、检查应用是否启用沙盒:在终端执行 codesign -d --entitlements :- /Applications/AppName.app,输出中存在 com.apple.security.app-sandbox 即表示已启用。
2、验证沙盒运行状态:启动应用后,在 Activity Monitor 中选中该进程,点击右键“显示 Inspector”,在“Sandbox”栏确认显示“Yes”。
3、若需自定义沙盒权限(如允许访问特定用户文档子目录),须在开发阶段修改 entitlements 文件,并使用 codesign --entitlements 重新签名。
三、配置 Launch Services 数据库的用户级作用域
Launch Services 负责管理应用与文件类型的关联关系(如双击 .pdf 默认用哪个程序打开)。其数据库分为全局(/Library)和用户级(~/Library)两层,用户级条目仅对当前账户生效,可实现文件类型处理行为的账户隔离。
1、重置当前用户的 Launch Services 数据库:lsregister -kill -r -domain user。
2、强制重新扫描 ~/Applications 下的应用:lsregister -f ~/Applications/*.app。
3、验证关联状态:执行 lsregister -dump | grep -A5 "AppName",确认输出中包含 user 字样且无 system 或 local 域标识。
四、限制辅助功能与自动化权限的跨账户继承
辅助功能(Accessibility)、自动化(Automation)、全盘访问(Full Disk Access)等隐私权限在 macOS 中按用户账户独立存储于 ~/Library/Application Support/com.apple.TCC/TCC.db。即使同一应用在多个账户安装,各账户必须单独授权,无法自动继承。
1、以目标用户身份打开“系统设置 > 隐私与安全性 > 辅助功能”,点击左下角锁图标解锁。
2、点击“+”号添加应用,定位到该用户专属的 ~/Applications/AppName.app。
3、重复上述操作为每个用户账户单独授权,系统会为每条记录写入唯一 client_id 和 service 字段值。
4、验证权限隔离:切换至另一用户账户,执行 tccutil reset Accessibility 后,原账户的授权状态不受影响。
五、使用 launchd 用户代理(User Agent)实现服务级隔离
通过为每个用户部署独立的 launchd plist 文件(位于 ~/Library/LaunchAgents/),可启动仅限该用户上下文运行的后台服务或守护进程。此类进程受用户 UID、环境变量、keychain 访问权限约束,无法访问其他用户的内存空间或密钥链项。
1、在目标用户 ~/Library/LaunchAgents/ 下创建 plist 文件,例如 com.example.isolated-service.plist。
2、在 plist 中明确指定 <key>UserName</key><string>username</string>,确保运行身份锁定。
3、设置 <key>SessionCreate</key><true/> 强制在用户图形会话中启动,避免脱离桌面环境。
4、加载配置:launchctl load ~/Library/LaunchAgents/com.example.isolated-service.plist。
5、检查运行状态:launchctl bootout gui/$(id -u) 可终止当前用户所有 launchd 代理,验证其作用域边界。










