Skip to content

bug(macos): Core 代码身份变化后旧 TCC 授权显示开启但失效,preflight 误报就绪,重新授权后仍需刷新 System Events #157

Description

@JTropy

概述与影响

在本机 macOS 环境中,AgentDock 的屏幕录制及辅助访问已由用户授权,系统设置中的开关仍显示开启,但实际截图和窗口读取被拒绝。检查 TCC 日志后确认:授权记录绑定的是旧 Core 的 cdhash,当前同一路径下的 Core 已是另一个代码身份。

此外,重新登记当前程序并授权后,还出现两个诊断/恢复问题:

  1. Desktop Skill 的 preflight 返回 ok=true、warnings=[],但紧接着真实 AX 窗口读取仍返回 -25211。
  2. 原生权限检查已经允许,真实 AppleScript/System Events 调用仍失败;正常退出并重新启动 System Events 后才恢复。

这会阻断依赖截图和桌面操作的任务,而不是单纯影响提示文字。文件与命令工具仍可工作,容易让用户和 Agent 把问题误判成“用户没有打开权限”,反复要求用户授权。建议作为高优先级的桌面可用性与权限诊断问题处理。 本报告不主张绕过 macOS 权限检查,也没有观察到越权或数据泄漏。

环境

  • AgentDock 节点报告版本:0.9.0,darwin/arm64。
  • Desktop Skill:1.0.12。
  • sw_vers 实际输出:macOS 27.0,Build 26A428。
  • 检查日期:2026-09-26,UTC+8。
  • 连接:ChatGPT → NexusDock → 本机 AgentDock。
  • 实际启动方式:用户 GUI 域中的 launchd LaunchAgent,Label 为 com.uvwt.agentdock,不是把当前环境假定为新版 AgentDock.app 的 SMAppService 路径。
  • 实际 Core 路径:$HOME/.local/bin/agentdock。
  • LaunchAgent 的启动参数(用户路径已脱敏):
$HOME/.local/bin/agentdock
service
launch-core
--runtime-root
$HOME/Library/Application Support/AgentDock

这里报告的是这套实际运行方式;尚未验证所有安装渠道或其他 macOS 版本是否受影响。当前二进制对应的源码 commit、旧版本号及导致二进制变化的具体更新/替换步骤未确认,不能据此断言某次官方自动更新必然触发。

一、已确认的代码身份失配

对实际运行进程和磁盘上的二进制分别执行 codesign 检查,两者当前 CDHash 一致,排除了“进程仍在运行另一个旧文件”这一解释。

当前签名摘要:

Identifier=a.out
flags=0x20002(adhoc,linker-signed)
Signature=adhoc
TeamIdentifier=not set
CDHash=672587ba3924923108e8c491f5716a6cf2394bcd
# designated => cdhash H"672587ba3924923108e8c491f5716a6cf2394bcd"

但 TCC 返回的原有授权记录中,同一程序路径对应的是:

auth_value=2
granted=true
path="$HOME/.local/bin/agentdock"
code_requirement=cdhash H"a295c912e0bbc18173377f7aac1a889272803619"

上面是相关字段摘录,个人路径已替换。系统日志随后明确记录:

SecStaticCodeCheckValidity() ... from $HOME/.local/bin/agentdock :
cdhash H"a295c912e0bbc18173377f7aac1a889272803619"; status: -67050

系统对该错误的解释为:

-67050 code failed to satisfy specified code requirement(s)

独立复核也得到相同结果,而不只是依赖日志解释:

# 用原授权所绑定的 requirement 验证当前程序
codesign --verify --strict --verbose=2 \
  -R 'cdhash H"a295c912e0bbc18173377f7aac1a889272803619"' \
  "$HOME/.local/bin/agentdock"
# explicit requirement 验证失败,exit=3

# 用当前程序的 requirement 验证
codesign --verify --strict --verbose=2 \
  -R 'cdhash H"672587ba3924923108e8c491f5716a6cf2394bcd"' \
  "$HOME/.local/bin/agentdock"
# explicit requirement satisfied,exit=0

TCC 的 attribution chain 把这些请求的 responsible process 明确归到该 agentdock,具体调用方包含 osascript、System Events 和 screencapture。不是把 ChatGPT 或被操作的 Tinycast 的签名错当成授权主体。

可以确定的结论:旧授权确实存在且显示 granted,但其身份要求不接受当前 Core。 当前检查到的是绑定 cdhash 的 adhoc 身份,而非跨构建稳定的证书身份;需要维护者进一步核对对应安装/更新渠道的签名和迁移设计。

二、重新授权后的恢复过程与 preflight 问题

用户通过系统设置重新登记当前路径的 agentdock 并授权后,截图先恢复了,但辅助访问一度仍失败。

这一阶段 Desktop Skill 的 preflight 返回摘要:

{
  "ok": true,
  "checks": {
    "screenshot_ok": true,
    "applescript_ok": true
  },
  "warnings": []
}

紧接着实际读取 Tinycast 窗口的 System Events 调用仍报:

“System Events”遇到一个错误:“osascript”不允许辅助访问。 (-25211)

随后原生检查已经返回:

ACCESSIBILITY_ALLOWED=true
SCREEN_CAPTURE_ALLOWED=true

TCC 日志也已开始对当前 672587ba… requirement 返回 status: 0,并对 kTCCServiceAccessibility / kTCCServiceScreenCapture 报告 Allowed (System Set),但真实 System Events 窗口读取仍暂时失败。

在正常退出并重新启动 System Events 辅助进程后,同类窗口读取成功;进一步成功读到了系统设置窗口标题。没有重装或重新签名 Core,也没有修改 TCC 数据库、关闭 SIP 或放宽系统安全设置。

这与 System Events 辅助进程保留旧授权状态的现象一致,但具体缓存层及 macOS 内部原因尚未确认,不应把推断写成已确定的内部根因。

最终复核:

ACCESSIBILITY_ALLOWED=true
SCREEN_CAPTURE_ALLOWED=true
POST_INPUT_EVENTS_ALLOWED=true
截图测试成功
真实 AX 窗口读取成功

本机现已恢复;这不等于软件层面的身份稳定性与诊断问题已修复。

三、复核步骤与建议的升级回归场景

对已经出现该问题的环境进行复核

  1. 确认系统设置中 AgentDock 的相关权限开关已开启。
  2. 从真实 AgentDock 执行链调用 Desktop 的截图、preflight 和目标应用 AX 窗口读取,而不是仅在终端里运行同名命令。
  3. 核对 TCC 日志中的 responsible path、原授权 requirement,以及当前进程/二进制的 codesign -d --verbose=4 -r- 输出。
  4. 检查是否存在 granted=true 但 requirement 校验 -67050 的组合。
  5. 用户重新登记当前程序并授权后,再比较原生权限检查、preflight 和真实 AX 操作三者是否一致。
  6. 若仍有 -25211,在用户确认后正常重启 System Events,再做相同读取以验证恢复。该步骤是本机有效的恢复措施,不建议无提示地重启系统辅助进程。

建议维护者在隔离测试账户中补充

已授权旧构建 → 按实际支持的升级渠道安装另一构建 → 从原有启动方式执行截图/AX → 观察授权是否保留,或能否准确提示需要重新登记。

本次已真实观察并重复验证上述身份失配和恢复过程,没有为了复现再主动降级/升级一次,因此不宣称已完成完整的升级 A/B 对照。

期望改进

  1. 安装、更新与代码身份:检查受支持的 macOS 发布/安装方式,尽量保持 TCC 所依赖的身份规则稳定。对 adhoc/直接二进制或旧 LaunchAgent 路径,明确支持范围、升级影响及重新授权/迁移指引。
  2. 正确诊断,而不是仅提示“请开权限”:区分未授权、授权绑定旧身份,以及原生检查允许但实际辅助进程仍不可用。输出实际 responsible executable 与有效的恢复步骤,不要求用户盲目给 Python、Terminal、osascript 等所有程序加权限。
  3. Desktop preflight 覆盖真实能力:分别报告屏幕捕获、AX 与 Apple Events 的状态;无法验证的项应标为 unknown/not_checked。applescript_ok=true 不能等价于真实 AX 可用,也不应让整体结果表现为完整桌面能力已就绪。
  4. 授权后的恢复引导与实测:授权完成后重新执行真实窗口读取和截图;仍失败时给出经过验证的刷新/重启指引,并在会影响其他自动化的操作前让用户确认。
  5. 回归测试:覆盖代码身份变化、重新授权后长期运行辅助进程的状态,以及 preflight 成功但实际 AX 失败的情况。不能以关闭系统防护或直接改写权限数据库代替修复。

如果 Desktop 的诊断与恢复部分应由 agentdock-skills 跟踪,可以拆分关联 issue;这里先放在 Core 仓库,便于一并确认安装、签名与运行方式的责任边界。

隐私与证据范围

已去除用户名、节点 ID、域名、认证配置、无关应用列表与笔记内容;未上传包含账户信息的系统设置截图。所附日志和指纹来自本机真实检查,不包含凭据。已检索相关 TCC/签名/辅助功能 issue,未发现同类 macOS 报告。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions