Cua Driver 权限简化执行实录:从 Cua 自持同意弹窗到受信宿主与启动授权的演进落地
【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua
Cua Driver 的权限简化(Permission Simplification)是一轮对授权模型的系统性收敛改造:它移除了 Cua 自有的同意弹窗与横幅 UI,将残余的高风险授权(如已登录 Chromium 档案的附加)收敛到受信启动授权与宿主回调,同时强化了 bounded 清单模式、进程指纹与终态撤销语义。本文以仓库中的执行日志为主干,结合 Rust 核心、SDK 与公开文档的源码证据,梳理这一演进从计划、落地到验证的全过程,帮助读者理解standard/bounded/unrestricted三模式在当前版本中的真实实现边界与配置方式。
背景:为什么要做"权限简化"
在权限简化之前,Cua Driver 的授权模型存在两个结构性痛点:
- Cua 自持同意 UI:原生授权弹窗、横幅、辅助模式与平台级同意渲染器(
overlay-uicrate)由 Cua 自己渲染。但 Cua 并不适合充当"人类同意"的最终裁决者——提示框既可能被 Agent 通过像素/元素路径干扰,也把同意流与模型/工具通道耦合在一起。 - 同用户可伪造的批准工件:早期
existing_profile的批准是放在同用户可写临时目录中的 JSON 工件,schema 与 UUID 令牌格式公开,任何同用户进程都能直接伪造,而非经过browser-approve。Agent 控制的 PTY 是第二条更弱的伪造路径。
执行日志对应的目标很明确:把"谁有权限"从"Cua 自己弹窗"迁移到"受信启动配置 + 受信宿主回调",让 Cua 在安全边界上少渲染、多校验。日志的 Completion bar 归纳为九项交付:
- 落地调和后的
standard/bounded/unrestricted契约; - 保留对已认证 Chromium 档案的显式授权路径;
- 移除Cua 自持同意弹窗与横幅行为;
- 保留矢量语义光标并新增净化后的公共会话徽标;
- 同步更新 Rust、CLI、MCP、Python、TypeScript、安装器、示例与公开文档;
- 在精确 review SHA 上通过 macOS、Windows、Linux X11、Linux Wayland 与 Linux headless 验证;
- 记录 macOS / Windows / Linux 的游标与交互视频;
- 合并已验证的依赖与完整实现;
- 不发布组件级 release(这是工程收敛,不是功能发版)。
授权模型的落地形态:启动期固化的三模式
权限简化的实施基线建立在既有的三模式授权模型之上。日志中"standard / bounded / unrestricted 契约"的调和落地,在 authorization.rs 中有完整对应:
PermissionMode::{Standard, Bounded, Unrestricted},通过CUA_DRIVER_PERMISSION_MODE环境变量或 CLI--permission-mode在启动时解析一次,之后不可由工具调用或传输参数修改(日志原文:"The mode is resolved once at daemon startup and cannot be changed by a tool call")。- 三个模式的语义沿用既定设计:
standard是默认且无提示驱动的模式,bounded必须配合能力清单(capability manifest)无人值守运行,unrestricted只有在显式危险确认(--dangerously-bypass-approvals或CUA_DRIVER_DANGEROUSLY_BYPASS_APPROVALS=1)后才生效,且只能压制提示、不能放宽任何策略层。
落地代码还明确了模式与能力策略的分工:authorization.rs第 1-6 行的模块注释直接写道 "Capability policy answers whether an operation is inside the configured ceiling. Permission mode answers whether an otherwise-permitted operation also needs trusted human consent." 即策略回答"能不能",模式回答"要不要人确认"。
描述符与溯源基础:行为矩阵、进程指纹与启动授权
每个审核过的强制适配器都带有行为矩阵
日志要求 "Added an explicit allow, deny, manifest, or grant behavior matrix to every reviewed enforcement adapter"。这体现在authorization.rs的EnforcementAdapterDescriptor与ENFORCEMENT_ADAPTERS静态清单中:每个适配器声明了自己的风险等级(R0–R4)、资源类型、scope 键、授权要求、撤销触发、稳定拒绝码与enforcement_by_mode/profile_behavior三模式行为。例如:
browser_prepare.isolated:R1,Routine(standard 放行、bounded 依清单、unrestricted 压制提示);browser_prepare.existing_profile:R2,GrantInStandard(standard 需要显式启动授权或受信宿主决策),idle TTL 30 分钟、absolute TTL 8 小时;browser_unbounded_script(page[action=execute_javascript|...]):R3,UnrestrictedOnly,稳定拒绝码unbounded_operation_requires_unrestricted——在 standard 与 bounded 中根本不可授予;os_permission_prompt(check_permissions[prompt=true]):Denied,拒绝码os_permission_prompt_requires_trusted_host——操作系统权限提示不得由 Agent 工具路径触发;devices、shell_and_network:NotExposed,风险类Unclassified——当前注册表中根本未暴露,也不添加"休眠适配器"或未支持的公开声明。
enforcement_adapters_for_call(authorization.rs 第 711 行起)按工具名与参数做合取式多适配器组合:截图输出既是私有观察又是文件写出,轨迹录制既是观察又是文件输出,任意页面脚本既是后果性操作又是显式无界操作——每个边界都必须满足,而不是只取最高风险项。
进程指纹取代 PID 所有权记录
日志中 "Replaced PID-only process ownership records with process fingerprints" 是本次简化的关键安全强化。在 browser/grant.rs 中,浏览器授权授予(ExistingProfileGrant)携带ProcessFingerprint(含 PID、启动时间、可执行文件等),并在matches比较中参与判定。配套机制是:
- 启动时运行进程快照 + 启动后证明:只有新观察到的进程才能进入运行时所有权注册表;
- 派发时指纹再证明 + 陈旧溯源清理:终止 driver 自持进程前必须重新证明指纹并清除过期溯源;
- standard 模式下拒绝终止外来进程,且不弹出任何同意界面(日志原文 "Denied foreign-process termination in standard mode without opening a consent surface")。
这一组设计把"这个进程是不是我启动的"从可伪造的 PID 记录提升为可验证的进程身份证明。
bounded 模式落地:清单 v2、目录根与应用身份
能力清单版本演进
日志要求 "Added manifest version 2 while keeping version 1 loadable"。在 session_manifest.rs 中,版本解析支持1、2 或 3:v2 引入应用身份授予、实际目录根、浏览器档案种类与 driver-owned / foreign 终止规则;v3 进一步移除mode与ask.tools(ask语义在 v3 中按拒绝处理),并把档案行为从文件内移出。当前公开文档 permission-modes.mdx 中的推荐写法是版本 3,其中browser.profiles可声明kind: isolated与kind: existing_profile,apps按bundle_id(macOS)或规范绝对路径(Windows/Linux)声明,terminate: driver_launched仅允许终止当前运行时证明其启动过的进程实例。
路径根匹配的规范化
日志要求 "Made path-root matching component-aware and canonical-path based"。公开文档明确:文件根先 canonicalize,再按路径组件比较——共享字符串前缀或符号链接逃逸都不能获得访问权。session_manifest.rs的测试也验证了input/output目录 canonicalize 后,nested子目录写入会被拒绝(is_err())。
直接的无 Provider bounded 派发
日志特别记录:"Allowed an existing-profile browser binding directly from a matching bounded manifest, without a consent provider or indicator"。即在 bounded 模式中,只要清单精确覆盖了该档案的作用域,附加已登录浏览器档案是无人值守放行的,不再需要同意 Provider 或指示器。这与 standard 的"必须显式启动授权"形成模式差异,也正是"一个批准的会话清单支持长时间无提示工作"这一 bounded 产品语义的落地。
终态撤销:ended session、已撤销上下文与 revoke-all 闩锁
日志要求 "Added stable dispatch refusals for ended sessions, revoked authorization contexts, and a terminal runtime revoke-all latch",且 "Made revoke-all reject later calls even when they introduce a new public session label"。
对应实现位于 session_authorization.rs:授权上下文持有revoked: Arc<AtomicBool>,is_revoked()检查被置于派发路径上(第 272、299-300 行),已撤销上下文返回稳定错误 "authorization context has been revoked"。服务端在 serve.rs 中暴露revoke_authorization方法(session或all=true二选一),CLI 侧由cua-driver revoke --session <id>与cua-driver revoke --all触发。
公开文档对终态语义的描述是:revoke --all对该运行时代(generation)是终态的,之后的调用(包括匿名调用)一律返回authorization_suspended;即使重新start_session声明新标签也不会复活已撤销的授权代,必须重启运行时才能获得全新授权代。serve.rs中对应的断言测试验证了 "bulk-revoked session call must preserve the loud legacy transport refusal" 且 "must not invoke the tool"。
宿主集成与 UI 移除:--grant existing-profile与宿主回调
可重复的启动授权
日志要求 "Added repeatable--grant existing-profilelaunch configuration tomcpandserve, including proxy forwarding and restart refusal when an incompatible daemon is already live"。
在 cli.rs 中,--grant是 repeatable 字符串参数,帮助文本为 "Pre-authorize existing logged-in Chromium attachment for this runtime";其实现调用cua_driver_core::authorization::configure_launch_grants,把归一化后的existing_profile存入进程级OnceLock<BTreeSet<String>>。要点:
- 它是受信启动配置,绝不从环境变量或工具参数读取(authorization.rs 第 21-25 行注释);
--grant仅在 standard 模式合法,main.rs 第 90-92 行明确bail!("--grant is valid only in standard permission mode");- 不能修改已运行的守护进程,遇到不兼容的常驻 daemon 时要求以相同
--grant重启(cli.rs 第 1640 行附近); - 在
unrestricted启动时,main.rs 第 98-100 行会打印高严重性 DANGER 警告,明确该模式不能防御提示注入。
CLI 帮助文本还特别澄清:--dangerously-bypass-approvals只选择 unrestricted 并作为显式风险确认,与--no-permissions-gate(仅控制 macOS OS 权限 onboarding UI)是两回事——这也呼应该模型中对 "OS permissions" 与 "permission mode" 的术语区分。
公开的宿主授权与活动观察回调
日志要求 "Added the publicDriverAuthorizationHostcallback and content-freeDriverActivityObserverto the Rust, Python, and TypeScript SDK surfaces"。
- authorization_host.rs 定义了
DriverAuthorizationHosttrait:受信嵌入宿主为残余 standard 边界实现authorize(request),返回绑定到请求摘要的 Allow/Deny/Cancel。DriverAuthorizationRequest携带 nonce、generation、daemon 实例、模式、策略哈希、适配器 ID、风险等级、资源 JSON(注明"不得记日志或转发给模型")与人类可读摘要。模块头注释强调:该回调是不可变构造配置,从不作为工具暴露,Cua 不规定也不渲染同意界面。 - activity_observer.rs 定义了无内容事件:
AuthorizedAction、AuthorizationRefused、ActionFailed、GrantIssued、GrantRevoked、SessionStarted、SessionEnded。事件"绝不携带参数、页面文本、路径、键入内容、图像或原始资源身份",实现者应快速返回并把耗时工作交给后台。 - 两者通过 UniFFI 导出,绑定已重新生成到 Python(
python/src/cua_driver/_native.py)与 TypeScript(typescript/src/native/cua_driver_sdk.ts)。
移除 Cua 自持同意 UI
日志要求 "Removed the native Cua authorization modal, banner, helper modes, platform consent renderers, and the completeoverlay-uicrate"。当前 crate 列表(libs/cua-driver/rust/crates/)中已不存在overlay-ui,取而代之的是cursor-overlay与cursor-theme-cli等游标相关 crate,印证了"同意 UI 整体移除、矢量语义光标保留"的方向。同时日志明确:浏览器自有的 Chromium 连接提示与操作系统权限流被保留——移除的是 Cua 自己的同意层,不是浏览器/OS 的安全提示。
会话徽标:净化、稳定色与实时缩放
日志要求 "Added a renderer-owned public-session badge below the semantic cursor using bundled Inter artwork, sanitization, stable session color, and live backing scale",并覆盖 macOS、Windows、Linux X11 与 layer-shell 渲染,以及 GNOME Wayland helper API v6。
公开文档 permission-modes.mdx 对徽标的描述是:公开命名会话在游标下方显示其净化标签,使用会话颜色,剥离控制字符、折叠空白、截断长标签;游标与徽标都不是授权信号,隐藏游标同时隐藏徽标,headless 会话两者都不要求。这一设计刻意把"活动反馈"(游标)与"授权指示"(原先的同意横幅)解耦——安全指示不再依赖可被隐藏/定制的游标层。
公开契约与迁移指导:无提示的实用默认值
日志记录了对公开文档的全面更新:"Replaced prompt-heavy standard-mode guidance with the promptless practical default",并新增了模式矩阵、bounded 清单 v2 指南、启动授权工作流、SDK 宿主回调示例、活动观察者契约、撤销行为、同用户边界、会话徽标与 headless 行为。
当前文档中的落地形态包括:
- standard 的操作表:观察窗口/应用/桌面、点击键入滚动拖拽聚焦、driver-owned 隔离浏览器、上传下载截图录制重放已校验路径、修改 agent 可调游标设置均允许;终止 driver 证明其启动的进程需指纹再验证后允许;终止外来进程、运行无界旧 page 变更脚本、从 Agent 工具调用触发 OS 权限提示均拒绝;附加已登录 Chromium 档案需要显式启动授权或受信宿主授权。
- 能力清单:默认 deny by default,工具必须在
allow.tools中且每个跨域资源匹配清单;resources.browser.origins只绑定类型化浏览器适配器,含 origin 作用域的清单不能同时允许click、type_text等绕过类型化适配器的通用输入工具(加载时直接拒绝,拒绝文本见文档原文);每次导航都校验 origin 集合。 - 授权栈:硬不变量 → 内建工具与风险映射 → 管理策略 → 用户策略 → 档案行为 → 能力清单 → 残余边界的启动授权/受信宿主决策,每层只能收窄。
- 撤销:
revoke --session <id>结束单个公开会话(会话标签 tombstone 直至显式start_session重新声明);revoke --all终结整个运行时代。
验证门禁:测试数量、文档构建与发布纪律
执行日志在各检查点给出了可复核的验证数据,并在本地 review 门禁中再次确认:
- 描述符与溯源基础:
cargo test -p cua-driver-core --lib413 passed,cargo check --all-targets通过; - 宿主集成与 UI 移除后:core/SDK/cursor 单测482 passed,
cargo test -p cua-driver单测136 passed,TypeScript 包套件6 passed,Python 包套件28 passed、3 skipped(跳过项因未暂存捆绑可执行文件); - 本地 review 门禁:文档生产构建通过(93 个静态页面)、文档链接检查0 errors、hygiene 检查通过、
cargo fmt --all -- --check通过、聚焦 Clippy 覆盖变更的 core 与 cursor crate。
发布纪律同样明确:合并已验证依赖与完整实现,但不创建或发布组件级 release——本轮是架构收敛而非对外发版,跨平台证据(macOS/Windows/Linux X11/Wayland/headless 的游标与交互视频)在日志末尾仍标记为待各环境完成后补充。
安全边界与适用前提
无论是日志、计划还是公开文档,都在关键位置重复同一个边界声明:Cua Driver 的授权模型只对"受限于其协议"的 Agent 构成边界。拥有同 OS 用户任意代码执行能力的 Agent 可以绕过 daemon——除非 daemon、策略、socket、浏览器与 Agent 之间被 OS 沙箱、服务身份、VM 或等价外部边界隔开。
换言之,权限简化交付的是"更少的 Cua 同意 UI + 更硬的启动时契约 + 更可验证的进程与资源身份",而不是把普通桌面变成安全桌面。实际使用时的正确姿势是:standard 日常使用配合--grant existing-profile显式授权,bounded 无人值守必须审查并批准能力清单,unrestricted 仅限一次性或完全受信环境;残余标准边界在没有启动授权或宿主回调时返回结构化authorization_required拒绝,而不会弹出 Cua 自持弹窗——这正是本次简化最核心的行为变化。
相关源码与文档入口
- 执行日志:permission-simplification-execution-journal.md
- 原始计划与设计:driver-permission-modes-and-consent-plan.md、permission-adapters-and-session-modes-plan.md
- 核心实现:authorization.rs、session_manifest.rs、session_authorization.rs、consent.rs
- 服务与 CLI:serve.rs、cli.rs、main.rs
- SDK 宿主接口:authorization_host.rs、activity_observer.rs
- 公开文档:permission-modes.mdx、how-permission-policies-work.mdx
【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考