关于 macos-permissions
macos-permissions 是用于诊断和修复 macOS 权限问题的操作技能,面向处理权限对话框及受保护资源访问失败的 Agent。它要求先观察实际请求与责任进程,再依据证据选择 TCC 或 Keychain 路径,并验证原操作结果。
主要功能
- 01先观察并分类权限问题
- 02追踪 TCC 请求责任进程
- 03区分不同权限故障原因
- 04依据证据指导权限修复
- 05在原执行上下文验证访问
适用场景
- 01排查 Full Disk Access 反复提示
- 02诊断受保护资源访问被拒
- 03处理 Keychain 访问故障
- 04检查更新后权限失效
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ daymade/ claude-code-skills --skill macos-permissions安装后在 Claude Code 中输入/macos-permissions确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/automated-full-disk-access.mdkeychain-dialog-recovery.mdtcc-mechanics.mduv-fda-trap.md详细介绍
macOS 权限对话框
先观察并判断报告的问题
执行中的 Agent 会保留用户描述的症状:即使对话框中包含密码字段,如果无法点击、输入内容或关闭,就需要诊断交互问题。不要把这条报告替换为输入密码的说明。
在选择子系统或指出其所有者之前,先查看实际对话框。使用主机允许的观察工具;如果已获授权且允许观察整个屏幕,请使用 capture-screen 的全屏路径,不要调出窗口。无法控制某个受保护应用,并不能识别未查看的对话框,也不能证明所有观察方式都不可用。遵守拒绝的适用范围;切勿切换工具以绕过主机限制或 GUI 锁定。
| 观察到的对话框或故障 | 处理方式 |
|---|---|
已确认的钥匙串项目访问故障、login 钥匙串密码,或被阻止的钥匙串窗口 | 阅读钥匙串恢复 |
| 隐私资源请求,或在没有可见对话框的情况下操作失败 | 继续执行下方的 TCC 流程 |
| 脚本、Git 钩子或特定应用的确认请求 | 通过所属任务/工具检查该请求;不要更改 TCC 或钥匙串设置 |
| 内容或所有者仍未知 | 保持未知;仅获取缺失且获准的观察信息,或询问用户可见文本 |
这些是操作人员的判断,不是自动对话框分类器。
TCC 诊断
macOS 通过 TCC(透明度、同意与控制)控制每个应用对每种资源的访问。TCC 会在其数据库中记录权限决策,并控制进程可执行的操作。几个常见陷阱需要采用不同的修复方法:
| 陷阱 | 症状 | 修复位置 |
|---|---|---|
| 授权对象错误 | 对话框显示 python3.11/2.1.232/node;你已授权该对象,但仍会收到提示 | 下方的归属陷阱 |
| 授权无法持久生效 | 曾经有效,但二进制文件/uv/CLI 更新后又出现提示 | references/uv-fda-trap.md |
| 静默拒绝 | 功能显示“不可用”,没有对话框,授权看起来处于开启状态 | references/tcc-mechanics.md § auth_value |
| 无法读取 TCC.db | 读取数据库时出现 Permission denied;需要 FDA 才能诊断 FDA | references/tcc-mechanics.md § SIP |
归属陷阱
首先复现报告的拒绝访问
执行 Agent 首先通过任务专属句柄和任何保留的结果检查原始受保护操作。对于相同的资源、请求方和执行上下文,复用当前证据。让仍在运行的请求继续使用其现有截止时间;在其终止状态尚不明确时,不要启动替代请求。如果当前证据缺失或已过时,请通过实际发生失败的请求方和上下文执行一次有界读取,然后再决定如何修复权限。文件列表、另一个终端、SSH 访问或前台运行都不能替代该操作。记录路径/资源、请求方、上下文和结果;这一步用于诊断,不是机械式的权限分类器。
如果此次读取成功,请报告 目前可访问;先前原因未知,并停止更改权限,除非某项特定的必要读取仍然失败。没有证据证明原因及其已得到纠正时,不要声称原因已修复;也不要仅为消除历史错误而添加 Full Disk Access、更改 ACL、重新连接共享挂载或重启共享主机。如果仍然失败,请按照下方的归因检查继续;仅凭 Operation not permitted 不能证明原因是 TCC。
对话框中的名称不能证明应该向谁授予权限。 macOS 会将请求归因于进程树中的负责进程,但显示的是访问文件的可执行文件名称;对于没有程序包的未签名二进制文件(由 uv 管理的 python、按版本安装的 CLI、node 辅助程序),显示名称只是路径的最后一部分,每个版本都会变化。向显示的名称授予权限,是最容易导致反复折腾的错误。
在打开“系统设置”之前,请检查请求以及任何可读取的授权状态:
# 1. Who is actually requesting — the responsible process in the attribution chain
/usr/bin/log show --last 30m --predicate 'subsystem == "com.apple.TCC"' --info --debug \
| grep -E 'from Sub:|responsible=|accessing=' | tail -20
# 2. Grant candidates, if this terminal can read the system database
sudo -n sqlite3 '/Library/Application Support/com.apple.TCC/TCC.db' \
"select service, client, auth_value from access where service='kTCCServiceSystemPolicyAllFiles' and client like '%<name>%';"
使用 from Sub: 找出候选请求方,然后核实其确切路径,并实际执行一次受保护读取,再决定要授权什么。若无法读取 TCC.db,则授权状态仍属未知;其 FDA 引导流程见 references/tcc-mechanics.md。
解读预检日志或已允许的授权记录时,请先阅读关联预检和授权证据,再决定如何修复权限。
决策树
| 情况是…… | 前往 |
|---|---|
| 用户要求自动完成 Full Disk Access 修复,或后台任务需要受保护文件 | references/automated-full-disk-access.md(先复用已验证的现有授权;否则操作“系统设置”并读取回执) |
点击 Allow 后对话框再次出现;或 LaunchAgent / uv run 任务每隔几分钟就弹出提示 | references/uv-fda-trap.md(识别请求方;添加授权前先遵循自动修复流程) |
需要完整的 kTCCService 目录、架构、auth_value/auth_reason 语义或 tccutil | references/tcc-mechanics.md |
| 读取 TCC.db 时出现“Permission denied” | references/tcc-mechanics.md § SIP 和 FDA 引导流程 |
| 某项已授予的权限在更新后悄然失效 | references/tcc-mechanics.md § 常见故障模式(关闭后重新开启,或执行 tccutil reset <Service> <bundle-id>) |
| Automation / Apple Events 的授权无法保留 | references/tcc-mechanics.md——控制方和目标方都需要授权 |
核心规则(均源自真实事件)
- 对话框名称 ≠ 负责的进程。 TCC 日志中的
from Sub:表示请求方;标题则是访问二进制文件的基本名称,并且会随版本变化。请按真实路径授权。 (2026-09-19:uv的 FDA 对话框显示python3.11;由于请求方是~/.local/bin/uv,授权 python、更改会话类型和固定版本均未奏效。) - 授权与精确的二进制文件路径绑定,而非身份。 未签名的可执行文件(由 uv 管理的 python、按版本区分的 CLI、node 辅助程序)每次路径变化时,对 TCC 来说都是一个新应用。因此,任何更新后都可能出现“昨天还能用,今天却开始提示”。这与 Claude Code 问题 #74234 / #84948 / #86706 的根本原因相同。
- “0 条命中/无法捕获”是检测手段的问题,而非结论。 在某些机器上,
fs_usage可能输出 0 字节;短暂运行的进程可能不在日志时间窗口内;空的 grep 文件看起来也和真正的零结果相同。要确定哪个操作触发了提示,请使用进程内的sys.addaudithook记录open事件,并与 tccd 时间戳对齐,而不是使用fs_usage。 - SIP 会以只读方式保护系统 TCC.db。 不能从命令行对授权执行
INSERT/UPDATE——必须通过 GUI 授权。auth_value可读,但不可写。 - 授予权限后,应先验证请求,再考虑重启。 请遵循下文的请求生命周期;是否需要重启取决于权限和应用,而非是否点击过 Allow。
授权或重置后
执行中的 Agent 通过其任务持有的进程/工具句柄检查原始请求,并在相同的请求方和执行上下文中重复指定的受保护操作。这些是操作员执行的检查;此 Skill 不会自动管理进程生命周期。
- 如果原始请求仍在运行,让它继续运行,并在其现有时限内等待实际结果。Automation/AppleEvent 请求在点击 Allow 后可以完成,无需重启请求方。关闭对话框或启用开关都不代表成功。
- 如果等待超时,重试前先检查原始请求的最终结果。工具等待结束本身并不能证明底层请求已结束;如果没有可用结果,就应将其状态视为未知。之后才点击 Allow,无法让已过期的请求成功。原始请求结束后,如有需要,发起一次新的、有时限的只读查询来验证访问权限;重复业务操作前,先检查是否已有副作用完成。
- 如果访问仍然失败,请检查精确的请求方、权限以及应用特定的重新启动要求。只有在该要求或观察到的故障表明有必要时才重启,并且只能重启任务持有的进程,或明确获准且工作能够保留的目标。在终止其他会话的进程或重启共享服务之前,先确认该精确操作已获明确授权,且其正在进行的工作能够保留。缺少任一条件时,应暂缓该修复,同时继续独立诊断。
- 执行任何必要的重新启动后,在真实上下文中重复受保护的操作。操作成功后就停止更改权限;仅有授权记录并不能证明任务可正常运行。
范围
此 Skill 负责权限诊断与修复。它不负责:构建应用的权限引导 UX(属于应用开发工作,不在此范围内)、设计 launchd 作业(macos-watchdog),或清理磁盘(macos-cleaner)——这些工具遇到 TCC 阻碍时会链接到此处。