云浏览器:适用于任何人工智能代理的安全远程浏览器平台
一种模型中立的远程浏览器服务的参考设计:网关、工作进程、WebRTC实时预览功能、审批流程、SSRF防护机制、回放功能以及所有配置选项。
AI智能体在处理网页逻辑方面已相当熟练,但要真正操控浏览器却比看上去更困难。点击按钮只是最简单的部分。一个值得人们信赖的浏览器智能体必须能够维持会话的持续运行,应对弹窗和重定向,理解动态界面,处理下载与上传操作,允许人类重新掌控操作,保护凭证安全,在执行重要操作前征求许可,之后还要清晰展示实际发生的情况。
Cloud Browser正是为解决这一系列问题而设计的:它是一种独立的浏览器执行服务,无需关心另一端使用的是哪种模型。
桌面代理、命令行编码助手、MCP客户端或自定义应用程序都可以使用它。该服务完全不包含大型语言模型。由代理决定应执行什么操作,而Cloud Browser则负责浏览器管理、安全边界设定、任务执行、实时视图展示、操作记录保存以及后续清理工作。
这种分工是该系统中最具决定性的架构决策。即便更换代理,浏览器平台依然保持不变;升级浏览器工作进程时,也无需重新编写代理代码。无论哪种客户端发起请求,安全策略的表现都一致。
接下来的内容将介绍该系统的架构设计、信任边界、交互模型,以及那些让浏览器自动化功能能够被企业实际使用的工程决策。
整体概览
人工智能代理可操作远程浏览器,而人类操作员可以实时监控、介入处理、批准敏感操作、查看截图,并在之后重新执行该任务。整个流程的设计刻意保持简单:
User
|
v
AI agent or agent application
|
| HTTPS API or MCP
v
Cloud Browser gateway
|
v
Isolated browser worker
|
v
Website
操作者通过带签名的WebRTC实时视图观察并指导工作者操作。
为何仅靠Playwright不够
Playwright虽是出色的自动化引擎,但它并非多用户浏览器产品。实际生产环境中的服务需要解决许多Playwright从未涉及的问题:
- 某个浏览器由谁拥有?
- 某个标签页对应哪项任务?
- 另一个代理能否重复使用未被分配给它的标签页标识符?
- 点击操作成功但网络响应消失时会发生什么?
- 如何在密码从未传递给模型的情况下完成登录?
- 什么机制能阻止浏览器访问云端元数据端点或私有网络?
- 当代理与操作者同时连接时,谁拥有控制权?
- 如何安全地存储和下载截图?
- 操作失败后哪些证据会保留下来?
通过为引擎设置明确的服务边界,平台可以每次都以相同的方式回答所有这些问题。
无计划执行
该服务仅负责处理请求,而不进行任何规划。它不会自行决定某笔购买是否应该完成或某条消息是否应该发送。这样的设计使其能够在不同的代理中保持通用性,同时清晰地划分两组职责。
在代理端:
- 理解用户的意图
- 确定下一步操作
- 解读浏览器当前显示的内容
- 在意图不明确时向用户询问
在云浏览器端:
- 验证发起请求的用户身份
- 隔离不同的会话和标签页
- 执行浏览器策略
- 验证每一个目标地址
- 执行相应操作
目标元素与过时引用
理想的目标元素是语义化的:当前文档中的按钮、文本框、复选框、菜单项或无障碍节点。而 Canvas 应用程序及高度定制化的界面仍需要坐标作为目标,这类目标的稳定性较差。在这种情况下,Cloud Browser 会检测指针所在位置,并报告实际位于该位置的元素的相关信息。
代理还可以指定其期望的角色或可见文本。如果目标位置的元素不符合要求,操作将直接失败,而不会误触其他元素。
页面会不断变化。模态框可以在观察与操作之间切换出现,导航功能可以替换整个文档,而弹出窗口则可成为当前的继续操作界面。为了解决这个问题,语义引用会被绑定到文档的特定版本上。任何修改或导航操作都会使之前的引用失效,尝试使用过时的引用则会引发stale_target错误。这样一来就能形成安全的循环结构:
Observe -> choose one action -> validate -> execute -> observe again
策略的存储位置
审批规则和网络规则不能仅存在于某个用户界面中,否则其他客户端可以直接连接并绕过这些规则。网关才是具有权威性的执行点。代理应用程序可以在其上添加更严格的策略,但任何应用程序都无法削弱服务本身的规则。
系统架构
参考实现包含三个主要模块以及一些辅助服务。
Agent clients
|
+-- Desktop agent UI
+-- Claude or another MCP client
+-- Codex or another coding agent
+-- Custom application or SDK
|
v
MCP adapter or direct HTTPS client
|
v
Cloud Browser gateway
|
+-- authentication and delegated identity
+-- tenant and task isolation
+-- request validation
+-- idempotency
+-- policy and approvals
+-- session manager
+-- signed live-view service
+-- audit and observability
|
v
Worker scheduler
|
v
Browser worker
|
+-- Playwright and restricted CDP
+-- tabs and popups
+-- semantic state
+-- browser actions
+-- screenshots and artifacts
+-- downloads and uploads
+-- WebRTC video source
+-- secure form filling
|
v
Approved web destinations
网关
该网关提供带版本的 HTTPS 接口。它会验证调用者身份、确定有效用户标识、检查任务归属权、应用配额限制、执行策略规则,然后将指令传递给相应的处理节点。指令会封装在关联的数据包中传输,其中包含协议版本、请求 ID、任务 ID、可选的会话 ID、指令名称以及限定参数。那些会改变系统状态的指令还需要一个幂等性键。
返回的结果和错误信息都有结构化的格式。禁止通过随机堆栈跟踪或原始服务故障让浏览器内部信息泄露出去。
MCP 适配器
支持MCP的智能体通过一个经过精简设计的适配器进行连接。Chromium从未在该适配器内部运行,它也不包含任何浏览器策略。该适配器的唯一功能是将工具调用映射为网关请求:通过相应的browser_*工具来打开标签页(browser_open_tab)、读取状态、点击操作、截取屏幕截图或结束会话。这样一来,多个智能体产品可以共享同一个网关,且不会有任何特定于供应商的组件侵入工作进程。
经过签名的实时视图URL会被适配器阻隔,不会传递给模型。智能体所接收的只是无害的展示数据:是否存在实时视图、显示的是哪个标签页、谁拥有控制权以及该视图的有效期限。只有经过信任的用户界面才能获得具备签名功能的查看权限。
浏览器工作进程
每个工作进程都拥有独立的浏览器进程或上下文。标签页、导航、语义提取、输入操作、截图、下载、上传、剪贴板管理、对话框以及浏览器事件均通过该进程处理。Playwright负责大部分自动化操作,而少数只读操作则可能需要启用受限的CDP功能。绝不会提供无限制的CDP访问作为通用解决方案。
这种限制非常重要,因为原始CDP功能能够访问cookies、存储数据、调试目标、任意代码执行能力以及浏览器内部结构。安全的产品只会暴露任务所需的最低限度功能。
会话管理器
会话管理器掌控着权限链:
tenant
-> principal
-> task
-> session
-> tab
-> operation
不透明标识符的作用范围仅限于该任务链。在一个任务下生成的标签页标识符无法被其他任务使用,即便这两个任务恰好共享同一个底层浏览器进程也是如此。管理器还负责处理租约、空闲超时、控制状态、保留的标签页以及配置文件的生命周期和最终处理。
浏览器配置文件与持久性
配置文件共有三种类型。临时配置文件仅存在于短暂的会话中,任务结束后即消失,因此默认提供了最强的隔离性。任务配置文件仅持续一个任务的时间,并与其他所有任务保持独立。持久配置文件则允许同一用户在不同的任务之间保留cookies和已登录网站的会话状态。
Chrome 在每个配置文件目录中只允许一个活动进程,因此同一用户的所有任务可以共享同一个浏览器进程,但每个任务仍保留自己的标签页、选中内容、实时帧、剪贴板状态以及控制权限。
持久化配置文件需要更严格的操作管控:
- 只有配置文件的所有者才能读取该目录。
- 底层的磁盘或存储服务应对静态数据进行加密。
- 用户需要能够登出并清除存储的配置文件。
- 访问权限需严格限制在特定的租户和主体范围内。
- 读取浏览历史记录需要获得明确授权。
- 工作人员绝不会将原始 Cookie 或身份令牌交还给代理程序。
一个命令的执行流程
所有操作都遵循相同的可预测步骤:
- 首先对服务调用者进行身份验证。
当传输失败发生时,而浏览器可能已经采取了相应操作,网关会返回outcome_unconfirmed状态。此时客户端必须调整浏览器当前的实时状态,而非盲目重复该操作。在预订、提交表单或发送消息等场景中,这一点尤为重要,因为自动重试可能会导致实际操作出现重复。
通过WebRTC实现实时查看
由于无法看到云浏览器的运行情况,很难对其保持信任,因此Cloud Browser提供了通过WebRTC实现的交互式实时查看功能。视频作为媒体流传输,而指针、键盘、剪贴板、状态、审批及交接等事件则通过有序的DataChannel传输。HTTP仅用于有限的请求-响应信号传递,且不存在额外的WebSocket图像流。
通过代理协议反复发送截图会降低效率,因此WebRTC方案能够减少延迟,避免快速交互被普通工具的响应所干扰。指针坐标会根据视频的实际范围进行映射,包括黑边区域在内。滚轮事件会被标准化并合并处理,键盘快捷键则遵循观看者所使用的平台规范,而确认信息则用于区分已排队、已发送、已更改、已被拒绝以及仍在等待处理的输入。
控制权的来回交接
初始时观看者处于观察模式,控制权由代理持有。用户可通过点击浏览器界面或按下控制按钮来请求获取控制权。状态机的工作逻辑十分明确:
Agent control
-> handoff pending
-> user control
-> release pending
-> agent control
Any state
-> finalized
虽然用户拥有控制权,但代理程序的输入会被阻止。控制权限仅限于当前任务范围,若网站打开新窗口,则会遵循所选的弹出窗口规则。过时的视频帧无法授予控制权,延迟的消息也无法将控制权悄悄交还给代理程序,因为网关始终掌握着当前状态的决策权。
保护观看者本身
实时查看链接是一种具有短暂有效期的、经过HMAC签名的功能,它与特定的租户、主体、任务、会话及标签页绑定,并在任务结束时失效。默认情况下禁止帧嵌套功能。若要将该查看器嵌入到受信任的代理应用程序中,部署时需在内容安全策略中明确列出所有允许的父源地址;通配符、路径、凭证、查询参数及片段均不可作为帧嵌套的源地址。
所有这些措施都是为了防止恶意网站嵌入查看器,在其上方添加一层不可见的界面,诱使用户点击“接管控制”或“批准”之类的按钮。
安全登录
密码绝不能传回模型、出现在操作时间线中或被记录到审计日志里。两种登录模式能够确保这一要求得到遵守。
其中一种模式是手动控制:代理将浏览器交给用户,由用户在网站上直接登录,之后控制权再回到代理手中。
另一种模式是专用的安全认证挑战。在这种方式中,工作节点会定位当前文档中的特定可见字段,而受信任的查看器则会显示一个经过掩码处理的凭证表单,其中注明确切的目标源地址。用户输入的内容会直接从查看器传送到表单填充服务,进而填入经过验证的浏览器字段中。该挑战会与源地址、任务、会话及标签页、文档生成方式、框架路径、选择器、预期的字段类型以及短暂的过期时间相关联。模型只能看到非机密的状态信息。
基于二维码的登录也可以安全地实现。工作节点会捕获可见的二维码图像,验证其可解码性,随后丢弃解码后的数据,并仅在安全的实时查看器中显示该图像。二维码中的承载值永远不会传递给代理程序。
在采取后续操作前的审批
允许用户访问某个网站与允许其在该网站上执行特定操作是两回事。允许代理人打开餐厅页面并不等同于授权其进行预订,能够进入在线商店也不意味着可以完成购买。Cloud Browser会在操作执行时评估相关风险。对于以下操作可能需要获得批准:
- 预订餐桌或预约时间
- 购买商品或付款
- 编辑账户信息或权限设置
- 删除任何内容
- 代表用户发送消息
- 存储凭证信息
- 上传文件
- 授予浏览器权限
- 传输敏感数据
每项审批都对应一个特定的操作、目标、目的地、文档以及数据类别组合,因此页面更改后或用于其他按钮时便不再有效。敏感数据的传输会独立于最终操作进行判断。在第三方表单中输入电子邮件地址时,可能需要在点击“提交”按钮之前获得与该目的地相关的审批,并另行确认。最终仍由用户进行审批,Cloud Browser负责执行,而代理应用程序则负责呈现决策结果。
截图、记录与回放
截图有助于快速理解内容、提供持久证据以及进行故障诊断。截图请求会返回一张可立即显示的图片以及一个不透明的工件标识符,且服务器文件系统路径永远不会传递给代理程序。这些工件属于对应的任务,有效期较短,存在大小和数量限制,通过签名过的路径传输,只能下载到配置好的本地目录中,并以仅所有者可访问的权限写入,而不会覆盖现有文件。
成功的浏览操作还可以生成有时间范围的截图时间线。每条记录都包含时间戳、主机名、来源地址、操作摘要以及可选的截图工件。滑块让用户能够查看更早的浏览器状态,而选择“实时”则可返回当前的WebRTC会话。
敏感操作会得到特殊处理。凭证输入内容绝不会被记录,而当某个操作涉及传输敏感信息时,时间线会仅保留最少的元数据,并刻意不显示截图。
回放功能不仅仅是为了视觉上的便利,它还能解答实际问题:
- 在点击操作之前,界面上显示了什么?
- 过程中是否有弹出窗口出现?
- 是否有其他元素覆盖在目标元素之上?
- 之后页面上是否有任何可见的变化?
- 任务是因网站问题停滞,还是等待用户批准?
弹出窗口、重定向及异常页面
实际的工作流程很少只停留在一个标签页中。预订流程可能会弹出窗口,身份验证服务可能需要在多个来源之间切换,办公文档可能会尝试启动桌面应用程序,而会议页面则可能同时提供应用链接和网页备用方案。Cloud Browser将这类切换视为重要事件。
如果某个操作会打开新窗口,平台会记录这个新标签页,将其选为当前任务的处理界面,并将其接入实时视图;当用户接管控制权时,控制权就会转移到该标签页。如果某个页面试图启动原生协议,比如会议应用,浏览器会说明外部应用程序不可用,而不会假装点击成功。如果该网站有安全的网页备用方案,代理或用户可以主动选择使用它。
该平台无法绕过验证码、浏览器安全拦截页、付费墙、设备信任要求或类似的防护措施。一旦出现这些机制,系统会将其视为限制并告知用户。
网络安全与SSRF
由于远程浏览器也充当网络客户端,若不加控制地进行导航,它可能被用作SSRF工具。在工作进程建立连接之前,系统会先解析并验证目标地址。默认情况下,以下类型的目标会被拒绝:
- 回环地址目标
- 链路本地地址目标
- 云元数据服务
- RFC1918标准的私有地址范围
- 多播地址及其他预留地址空间
- 不在支持列表中的任何URL方案
通过为每个租户设置允许列表和阻止列表,可以进一步强化安全措施。
某些企业架构会使用分离式 DNS 或安全网页网关,将经过审批的内部主机名映射到私有网络或运营商级 NAT 地址。此类例外情况必须明确界定、范围有限,仅限于可信域名,并通过部署配置来设置,这样对应的主机名就不会演变成通向整个私有网络的路径。重定向、弹出窗口、iframe、service-worker 请求以及 DNS 重新绑定都受同一网络策略约束,因为仅审核第一个 URL 是不够的。
命令注入与不可信页面内容
浏览器工作进程将页面内容视为数据而非指令。页面可以显示“忽略之前的指令”之类的文字,或发布声称某项操作安全的工具说明,但这两者均不具备任何授权效力。
页面通过 WebMCP 宣告的工具与页面 URL、文档生成方式、注册标识符以及所观察到的架构相关联,且这些工具的描述绝不可被信任。除非部署环境明确授权该特定来源,否则页面提供的 readOnlyHint 也无法跳过审批流程。语义快照也遵循相同规则:内容层面的推理由代理负责,而是否授予浏览器权限则完全由网关决定。
下载、上传与剪贴板
下载的文件会被作为任务专属的资产保存,因此不会暴露任何工作节点的路径。上传功能需要与某个事件关联的文件选择器,以及位于已配置的上传根目录下的源路径。如果符号链接指向非允许的目录,系统会拒绝处理;在设置文件之前,工作节点还会检查选择器是选择了一个文件还是多个文件。
每个任务都有独立的剪贴板状态。文本和有大小限制的二进制MIME类型数据可以通过实时查看器进行同步,浏览器权限会被严格限制并在使用后取消。在持久化的浏览器上下文中,授予某个任务的剪贴板权限不得继续用于其他任务。
生命周期与清理
即便代理从未正常完成任务,也必须执行清理操作。该服务会接收明确的轮次结束信号,用以区分已完成、中断、停止以及子代理停止的轮次,而其启动的清理操作是有限且可重复执行的。每个标签页可以带有以下三种标记之一:
- 正在处理的标签页,轮次结束时关闭
- 需交付的内容,为用户保留
- 待继续处理的标签页,保持开放状态供用户继续操作
局限于单个轮次的标记在相应操作完成后就会被清除,因此必须在后续轮次中刻意再次保留该标签页。进一步的清理工作则来自会话租约、空闲超时处理、资源过期清理、孤立配置文件清除以及平滑的网关关闭机制。
在不泄露隐私数据的前提下实现可观测性
网关日志记录了涵盖会话创建、导航、策略决策、控制权移交、数据变更、故障以及清理操作等在内的各类运行事件。审计记录应保存标识符和结果,而非凭证或页面内容。URL会尽可能截取到安全的部分,而查询语句、表单值、密码、令牌以及个人数据则会被遮蔽或删除。
有用的运行状态信号包括:
- 网关及工作节点的延迟情况
- 当前存在的会话数和浏览器数量
- 已连接的WebRTC对端
- 发生的策略拒绝类型
- 目标数据失效的频率
- 尚未确认的结果
- 无法启动的工作节点
- 实时查看连接是否成功
- 已创建及已过期的临时文件
- 清理操作失败的记录
只有当视频真正进入播放状态时,观察者才会报告,因为仅仅生成一个带签名的URL并不能证明用户能够看到内容。
可靠性与压力测试
最棘手的浏览器自动化故障往往是那些悄无声息的:点击却没有任何效果、输入内容被重复提交、弹窗无人看到,或是操作在超时后被重新执行。因此,一个完善的测试套件必须涵盖远超出正常流程的多种情况。Cloud Browser会对以下方面进行测试:
- 同时处理大量用户和会话
- 任务之间以及不同结果之间的区分
- 必须具备幂等性的操作变化
- 对过时文档的引用
- 跟随弹窗的操作
- iframe和shadow root内的目标元素
- WebRTC的重新连接
- 控制权交接时的竞争条件
- 处于忙碌状态或短暂冻结的页面
压力测试应同时使用真实的 Chromium 工作进程与多个 WebRTC 观看端。单元测试能够很好地覆盖策略与协议逻辑,但浏览器启动、视频流传输、焦点切换、弹出框选择以及输入处理方面的竞态问题只有在真实负载条件下才会显现。
部署模型
参考架构可以作为一个节点运行,不过其接口设计是为更庞大的生产控制平面准备的。基本的部署方式会将这些组件串联起来:
TLS ingress
-> Cloud Browser gateway
-> isolated browser workers
-> encrypted profile and artifact volume
浏览器应在合适的 seccomp 配置文件下以低权限用户身份运行,其 CPU 和内存使用需受到限制,并为 Chromium 提供足够的共享内存。容器是一个实用的起点,而在风险较高的环境中,则可以为每个浏览器工作进程配置一个微虚拟机以实现更强的隔离效果。
企业级部署通常还会添加:
- 用于独立控制台的 OIDC 登录功能
- 代理程序之间的机器对机器认证机制
- 由可信后端传递给最终用户的身份信息
- 用于存储分布式租约和幂等性键的 Redis
- 用于记录持久事件的 PostgreSQL 或专用审计平台
- 用于存储相关文件的加密对象存储系统
- 负责分配工作进程的调度器
- 用于发放短期有效 WebRTC 凭证的 TURN 服务器
- 具备密钥轮换功能的机密信息管理工具
- 区域路由功能以及数据驻留控制机制
网关应仅能通过HTTPS从外部访问。普通HTTP仅适用于明确的回环测试环境,其他场景均不适用。
逐个参数配置
env文件用于设置网关的网络标识、浏览器行为、存储配置、隔离机制以及策略边界。应将其视为部署配置,而非应用程序源代码。下方的示例可以安全展示,因为其中的数值仅为示意,并不包含任何真实的令牌或签名密钥:
CB_HOST=127.0.0.1
CB_PORT=8787
CB_PUBLIC_URL=http://127.0.0.1:8787
CB_TOKENS=replace-with-a-long-random-token:tenant-example:agent-service:delegate
CB_MAX_SESSIONS_PER_PRINCIPAL=8
CB_LIVEVIEW_SECRET=replace-with-a-separate-random-signing-secret
CB_LIVEVIEW_FRAME_ANCESTORS=http://localhost:8088,http://127.0.0.1:8088
CB_HEADLESS=true
CB_SERVICE_WORKERS=allow
CB_BROWSER_CHANNEL=chrome
CB_EXTENSION_PATHS=
CB_PROFILE_MODE=persistent
CB_PROFILE_DIR=./var/profiles
CB_ARTIFACT_DIR=./var/artifacts
CB_AUDIT_FILE=./var/audit.log
CB_USER_AGENT=
CB_ALLOW_ORIGINS=
CB_BLOCK_ORIGINS=
CB_TRUSTED_PRIVATE_ORIGINS=*.company.example
CB_ALLOW_CGNAT_NAVIGATION=true
CB_REQUIRE_APPROVAL=false
CB_ALLOW_LOOPBACK_NAVIGATION=true
CB_SYNTHETIC_MEDIA_DEVICES=true
CB_HOST
这是网关监听的网络接口。
CB_HOST=127.0.0.1
使用 127.0.0.1 时,服务仅响应本地机器,当在同一台计算机上开发代理 UI、MCP 适配器及网关时,这是最安全的选择。容器可能需要 0.0.0.0,以便其网络或入口代理能够连接,但这并非将端口公开到互联网的理由;生产环境中的网关始终处于经过身份验证的 TLS 入口、防火墙规则及服务级授权之后。还需注意,CB_HOST 控制进程的监听地址,而实时查看链接中的 URL 由 CB_PUBLIC_URL 负责处理。
CB_PORT
这是网关所使用的 TCP 端口。
CB_PORT=8787
从 1 到 65535 之间的任意数字均可,开发环境默认值为 8787。该端口在所选接口上不得已被使用。如果反向代理或容器使用了其他外部端口,CB_PORT 仍为内部监听端口,而 CB_PUBLIC_URL 则是外部用户可见的地址。
CB_PUBLIC_URL
公共基础 URL 是网关在生成带签名的实时查看链接时所使用的地址。
CB_PUBLIC_URL=http://127.0.0.1:8787
它不仅仅是一个标签,因为用户界面会获取由此衍生的查看器功能,所以必须能够从显示实时视图的浏览器中访问到它。本地开发支持回环 HTTP:
CB_PUBLIC_URL=http://127.0.0.1:8787
远程部署需要一个可从外部访问的 HTTPS 源地址:
CB_PUBLIC_URL=https://browser.example.com
请勿在URL中包含路径、查询参数、嵌入的用户名、密码以及原始机密信息,并应在受信任的入口点或网关本身处终止TLS加密。还有一个需要注意的问题:127.0.0.1始终表示用户所在的机器。假设代理UI运行在笔记本电脑上,而网关则位于另一台服务器上,那么使用127.0.0.1生成的访问链接会返回到笔记本电脑,而无法到达网关。
CB_TOKENS
该变量列出了网关所接受的服务凭证。每条记录都遵循相同的格式:
<bearer-token>:<tenant-id>:<service-principal>[:scope]
委托的后端凭证如下所示:
CB_TOKENS=replace-with-a-long-random-token:tenant-example:agent-service:delegate
多个条目之间用逗号分隔。第一个字段是承载令牌,它位于HTTP的Authorization请求头中;该令牌长度应至少为20个字符,需通过加密安全的随机数生成器生成,并存储在密钥管理工具中。租户ID是最高的隔离边界,因此会话、任务、配置文件、标签页以及相关数据都不会跨越这一边界。主体名称指的是持有凭证的服务,在没有委托的情况下,会话将以该主体的身份运行。
可选的 delegate 功能允许受信任的后端发送一个 X-Cloud-Browser-Principal 标头,指定真正的最终用户。此时会话便归属于该用户,而审计日志则会单独记录是哪个后端代表其进行了操作。只有受信任的服务器端应用程序才应获得委托权限,桌面客户端或普通用户令牌则不应拥有此权限,因为否则它们可能会在租户内冒充其他用户的身份。
无论是已配置的令牌还是当前显示的令牌,在进行恒定时间比较之前都会被哈希处理,这虽能减少因令牌长度差异导致的时序泄露问题,但并不能保证已泄露的令牌安全。如果令牌出现在截图、代码仓库、终端记录或支持工单中,应立即更换该令牌。同时切勿将其重复用作 CB_LIVEVIEW_SECRET,因为两者保护的功能不同,需要独立生成。
CB_MAX_SESSIONS_PER_PRINCIPAL
该参数限定了一个有效用户可同时拥有的会话数量。
CB_MAX_SESSIONS_PER_PRINCIPAL=8
允许的值范围为 1 至 128,默认值为 8。设置此限制可防止意外的大量浏览器请求以及失控的代理程序,同时避免单个用户耗尽全部资源;它与网关级别的会话上限共同起作用。具体数值需根据工作进程的内存、CPU性能、配置模式以及预期的并发量来确定。即便持久化配置在用户的不同任务之间共享同一个浏览器进程,每个任务仍会占用标签页、流媒体、生成文件以及网关相关的资源。
CB_LIVEVIEW_SECRET
这是用于对实时查看功能进行签名的HMAC密钥。
CB_LIVEVIEW_SECRET=replace-with-a-separate-random-signing-secret
签名中包含的每个字段(租户、主体、任务、会话、标签页、有效期)都受到签名保护,因此修改任意一个字段都会使签名失效。可从外部访问的部署需要拥有长度为32个字符或更长的密钥;实际上这意味着至少需要从密钥管理器中加载32个十六进制或Base64格式的随机字节。如果密钥泄露,具备足够会话元数据的攻击者便能伪造查看器功能。密钥轮换会导致使用旧密钥生成的已验证签名失效,因此需将其与实时查看会话的到期时间保持一致。请将此密钥值存放在远离代理、浏览器页面、客户端包、日志及代码仓库的地方。
CB_LIVEVIEW_FRAME_ANCESTORS
该参数用于指定哪些受信任的Web应用程序可以在iframe中嵌入已签名的查看器。
CB_LIVEVIEW_FRAME_ANCESTORS=http://localhost:8088,http://127.0.0.1:8088
该网关会将此列表转换为浏览器内容安全策略中的frame-ancestors指令。如果该值为空,浏览器会发送frame-ancestors 'none'和X-Frame-Options: DENY,这样该页面虽可独立使用,但会被禁止被嵌入。如果列出了特定的源地址,则只有这些确切的地址才能对其设置框架,同时不会包含X-Frame-Options: DENY,因为这种较旧的头部字段无法指定多个源地址,反而会抵消允许列表的作用。
条目必须是精确的HTTP或HTTPS源地址;路径、URL凭据、查询参数、片段标识以及通配符均会被拒绝。协议、主机名和端口都很重要,因此以下三个地址属于不同的源地址:
http://localhost:8088
http://127.0.0.1:8088
https://agent.example.com
此设置与 CORS 无关。它的作用是保护功能强大的查看器页面免受点击劫持攻击,因此只需列出确实需要显示实时浏览器的接口。
CB_HEADLESS
该参数用于控制工作进程是否在无需原生桌面窗口的情况下启动浏览器。
CB_HEADLESS=true
当值为 true 时,Chromium 或 Chrome 会以无界面模式运行,用户通过 WebRTC 实时视图进行操作,而非通过本地的 Chrome 窗口。服务器和容器通常希望如此,因为这能减少桌面资源占用,并使自动化流程不受原生显示会话的影响。当值为 false 时,浏览器将以有界面模式启动,需要一个可用的显示设备,通常是像 Xvfb 这样的虚拟显示器,或是 Linux 系统上的桌面流式工作进程镜像;在 macOS 上则会打开一个独立的浏览器窗口,除非工作进程架构有所不同。更改此标志不会让 Cloud Browser 接管已打开的个人 Chrome 窗口,它仅影响工作进程自身管理的浏览器的启动方式。
CB_SERVICE_WORKERS
该参数决定网站是否可以注册并运行服务进程。
CB_SERVICE_WORKERS=allow
选择 allow 或 block;block 是更安全的默认选项。渐进式 Web 应用、视频会议客户端、办公应用以及大量使用缓存的网站通常依赖服务工作线程,如果没有这些线程,它们可能会出故障、在加载界面卡住或呈现冻结状态。启用服务工作线程有助于提升兼容性,但也会增加浏览器的网络处理和数据持久化负担,因此请事先确认服务工作线程的请求仍会遵守导航保护规则、出口规则、数据丢失预防机制以及租户策略。仅在对确实需要该功能的经过验证的应用程序中使用 allow,切勿将其作为通用解决方案。
CB_BROWSER_CHANNEL
该选项用于选择系统安装的浏览器版本,以替代 Playwright 自带的 Chromium 版本。
CB_BROWSER_CHANNEL=chrome
支持四种渠道:chrome、chrome-beta、chrome-dev和msedge。若留空,则使用已配置的Chromium可执行文件或Playwright包。当企业需要验证设备可信度、集中管理浏览器、推送策略或颁发客户端证书时,有时必须使用真实的Chrome或Edge版本。选择chrome不会加载用户的常规Chrome配置文件,因为配置文件仍来自CB_PROFILE_MODE和CB_PROFILE_DIR,因此Cloud Browser无法悄无声息地附加到个人交互会话中。该渠道必须安装在工作节点主机上,而且设备可信度验证可能还需要合适的配置文件、操作系统注册信息、证书、策略或扩展程序;此设置本身并不会建立企业级信任关系。
CB_EXTENSION_PATHS
以逗号分隔的已解压浏览器扩展程序目录列表。
CB_EXTENSION_PATHS=
若留空则不会加载任何未解压的扩展程序。列出的路径会通过扩展程序加载标志传递给受管理的浏览器,但此功能仅能在 CB_HEADLESS=false 且 CB_PROFILE_MODE 设为 task 或 persistent 时使用;临时上下文及纯无头模式无法安全地承载这些扩展。未解压加载仅适用于开发与受控测试。生产环境中的企业应通过 Chrome 或 Edge 的策略强制安装经过审批的扩展程序,锁定其标识符并更新来源,同时审查相关权限。由于扩展程序以浏览器权限运行,能够监控或修改网页活动,因此其来源、更新路径、权限及所有者均需纳入安全审查范围。
CB_PROFILE_MODE
该参数决定了浏览器状态的隔离方式以及登录状态的有效时长。
CB_PROFILE_MODE=persistent
该设置可选 ephemeral、task 或 persistent 模式。ephemeral 模式会创建一个不可重复使用的临时浏览器上下文,不设置可复用的配置文件目录,具备最强的默认隔离性,适用于匿名浏览或无需留下任何登录痕迹的操作。task 模式会为单个任务创建一个配置文件目录:Cookie 和状态仅在该任务期间存在,任务结束后会自动清理该配置文件。persistent 模式则让同一租户和有效主体的不同任务共享同一个配置文件,因此 Cookie 和网站会话能够持续到新任务启动或网关重启之后,不过每个任务仍保留独立的标签页所有权、当前选中标签页、剪贴板内容、实时流数据、临时文件以及控制权限。持久模式最为便捷,但风险也最高;应使用加密存储、严格的目录权限设置、明确的登出及配置文件清除流程,并限制空闲时间。
CB_PROFILE_DIR
存储基于配置文件的浏览器数据的根目录。
CB_PROFILE_DIR=./var/profiles
相对路径是相对于网关进程的当前工作目录来解析的。在容器环境中,如果需要确保配置文件在容器被替换后依然存在,应在此处挂载受保护的存储卷。网关会自行创建针对不同租户和主体的子目录,绝不会使用代理所指定的配置文件路径。这些目录应设置为仅所有者可访问,且不得提供下载功能。请勿将此设置用于真实用户的 Chrome 配置文件;复制或同时打开正在使用的配置文件可能会对其造成损坏,并使无关的浏览数据暴露给工作进程。
CB_ARTIFACT_DIR
用于存储任务生成的截图、下载内容、导出内容、回放图像以及其他相关文件的位置。
CB_ARTIFACT_DIR=./var/artifacts
相对路径仍从网关的当前工作目录进行解析。代理节点接收的是不可见的工件ID而非路径,每次获取操作都会检查租户、主体、任务、有效期及所有权信息。仅允许Cloud Browser服务账户对该目录进行写入操作,需限制工件的有效期、数量及大小,定期清理过期文件,对存储数据进行加密,并避免将临时工件无限期地保留在备份中。配置文件与工件具有不同的用途:截图可以发送给用户,而浏览器配置文件绝不能被视为可下载的工件。
CB_AUDIT_FILE
受限JSON Lines审计日志的路径。
CB_AUDIT_FILE=./var/audit.log
每一行都代表一个结构化的事件,可能包括会话创建、命令执行、策略拒绝、控制权移交、实时查看连接的结果、会话销毁或清理失败等。需记录发生事件的人和内容,而非表单值或页面内容,并对凭证、令牌、查询语句及敏感用户数据进行遮蔽或省略。在正式环境中,应将本地JSONL视为开发或传输格式,再将这些事件发送到具备保留策略、访问控制、完整性保护、警报功能以及针对不同租户的查询能力的持久化审计平台。
CB_USER_AGENT
用于可选地覆盖浏览器的User-Agent字符串。
CB_USER_AGENT=
最好保持为空。浏览器构建时会生成一个标准的 Chrome 身份信息,并提供相应的客户端提示,以避免请求头、navigator.userAgent 和 navigator.userAgentData 之间出现不一致。自定义字符串仅会覆盖 User-Agent,且不会生成对应的提示信息,某些身份验证服务及机器人检测工具能够识别这种不一致。请勿利用此功能将旧浏览器伪装成新浏览器,或绕过网站的安全策略;应将其用于符合文档记载的兼容性要求,并在之后检查完整的浏览器身份信息。
CB_ALLOW_ORIGINS
租户的导航允许列表。
CB_ALLOW_ORIGINS=
如果列表为空,则除非有其他策略介入,否则公共的 HTTP 和 HTTPS 目标地址可以通过,而私有网络、元数据、链路本地、保留以及不受支持的目标地址仍会受到网络防护机制的拦截。一旦列表中有条目,每次导航都必须与至少一条规则匹配,这些规则可以是形如 https://portal.example.com 的精确源地址、形如 *.example.com 的通配符后缀,或是形如 portal.example.com 的纯主机名。在协议或端口重要的情况下,应使用精确的源地址;通配符可以覆盖基础主机名及其子域名,因此请谨慎使用。仅列入允许列表并不足以授权私有 IP 地址,因为 DNS 分类和受信任的私有源地址策略仍会独立进行评估。
CB_BLOCK_ORIGINS
明确的导航拒绝列表。
CB_BLOCK_ORIGINS=
这些规则与允许列表采用相同的三种格式,且会首先查询该列表,因此同时符合两个列表条件的内容都会被阻止。常见应用场景包括敏感的管理端点、不受支持的应用程序、已知危险的地址,或是需要从更广泛的允许列表中排除的子域名。即便该列表为空,网络分类功能依然有效。
CB_TRUSTED_PRIVATE_ORIGINS
用于指定可能解析为私有地址或CGNAT地址的企业主机名。
CB_TRUSTED_PRIVATE_ORIGINS=*.company.example
其存在的原因是分片 DNS 设置,即经过审批的公司主机名在 VPN 或内部网络上的解析结果不同。规则采用导航列表语法。应仅限制访问组织拥有的域名,切勿仅仅因为某个应用程序出现异常就添加通用的通配符或主机名。可信匹配项可允许 RFC1918 或 CGNAT 目标,但绝不允许回环地址、链路本地地址、云元数据地址、多播地址或保留地址。应像处理 SSRF 异常一样对其进行审查;平台需要能够控制 DNS、出站连接以及每个可信后缀的所有权。
CB_ALLOW_CGNAT_NAVIGATION
允许访问运营商级 NAT 范围 100.64.0.0/10。
CB_ALLOW_CGNAT_NAVIGATION=true
其默认值为 false。在某些企业网络中,VPN或安全网页网关会通过CGNAT地址空间内的地址来提供公共服务或内部服务。开启此开关可允许这些服务访问,并可能解除浏览器的本地网络访问限制,从而避免页面无法到达该虚拟地址。此功能的作用范围比仅信任某个主机名更广,因此如果只需信任已知的企业域名,则应使用 CB_TRUSTED_PRIVATE_ORIGINS。RFC1918、环回地址、链路本地地址、元数据地址、多播地址以及保留地址段仍保持封闭状态,但网络访问范围依然会大幅扩大,因此仅应在受控的企业环境中启用此功能。
CB_REQUIRE_APPROVAL
为被归类为重要级别的命令启用网关的常规审批机制。
CB_REQUIRE_APPROVAL=false
当设置为 true 时,相关命令会一直等待直到收到确切的操作时间批准。若设置为 false,则取消限制,这在已有可信代理应用实施更严格规则的情况下是个合理选择。不过安全功能并未被禁用,诸如敏感数据传输、删除、支付、预订、代他人发送消息、账户或权限更改、历史记录访问以及非机密页面工具等已知风险仍需批准。控制则是另一个维度:只要用户持有浏览器,代理操作就会一直被阻止。对于由多个代理共享的独立产品,通常保持网关限制开启更为明智,因为这样安全措施就不必依赖每个客户端都能正确执行策略。
CB_ALLOW_LOOPBACK_NAVIGATION
一个开发模式开关,允许开发者浏览器访问回环地址(localhost、127.0.0.1 或 ::1)。
CB_ALLOW_LOOPBACK_NAVIGATION=true
默认值为 false。自动化测试以及运行在 Worker 所在机器上的本地 Web 应用都能从中受益。它无法让远程浏览器访问用户的笔记本电脑,因为在远程环境中 127.0.0.1 代表的是远程环境。请勿在生产环境中随意启用此功能:回环访问可能会暴露内部管理端口、开发服务器、调试界面,以及那些基于“不可信的网页内容无法访问这些资源”这一假设构建的服务。即便启用了该功能,主机名也必须仅能解析为回环地址,这样才能避免混合 DNS 响应被用来实现普遍的绕过。
CB_SYNTHETIC_MEDIA_DEVICES
为受管理的浏览器提供虚拟麦克风和摄像头。
CB_SYNTHETIC_MEDIA_DEVICES=true
默认值也为 false。无头浏览器通常不会显示任何媒体设备,而且一些会议和录制网站会在继续之前检查麦克风或摄像头,因此当未找到这些设备时页面就会显得卡住。虚拟设备可以让这些检查通过:麦克风没有声音,摄像头显示的是测试图案而非真实视频。此处没有任何内容会捕获任何人的真实麦克风或摄像头,也不应如此描述。如果该程序加入了真实会议,除非需要播放测试图案,否则应关闭摄像头。该网站仍可请求权限,而是否授予权限是与提供设备不同的决策事项。
将示例视为一种部署方式
综合来看,该示例配置描述的是一种本地开发环境:
- 网关仅在
8787端口上接受本地连接。
8088 端口提供。这可作为本地集成配置使用,但并非生产环境基准。在发布之前:需将公共网址改为HTTPS,定期更换所有密钥并将其存储在文件之外,禁用回环地址,缩小CGNAT和私有源地址的例外范围,审查service-worker的访问权限,启用网关审批策略,将配置文件及相关资源存储在加密的管理存储中,并将审计事件转发至持久化平台。
连接代理
具备MCP功能的代理可作为本地进程启动适配器,并将其指向网关。真实凭证不应存放在版本控制系统中,因此请使用此类占位符:
{
"mcpServers": {
"cloud-browser": {
"command": "node",
"args": ["/path/to/cloud-browser/packages/mcp/src/index.js"],
"env": {
"CB_GATEWAY_ENDPOINT": "https://browser.example.com/v1/browser",
"CB_GATEWAY_TOKEN": "retrieve-from-your-secret-manager",
"CB_DOWNLOAD_ROOTS": "/approved/output"
}
}
}
}
典型的交互过程如下:
Agent: browser_open_tab(url)
Cloud Browser: tab identifier, page metadata, safe live-view metadata
Agent: browser_get_state(tab)
Cloud Browser: revision-bound semantic state
Agent: browser_click(fresh target)
Cloud Browser: confirmed receipt, updated state, evidence
User: take control through signed viewer
Cloud Browser: block agent input
User: release control
Cloud Browser: restore agent input
Agent: browser_finalize_session()
Cloud Browser: close working tabs, revoke authority, expire artifacts
这与单个智能体内的浏览器工具有何不同
许多智能体产品都会自带浏览器工具。Cloud Browser旨在成为众多智能体背后的浏览器平台,其价值源于多种特性的结合:
- 对所使用的模型保持中立
- 会话可在远程持续保存
- 交互既支持语义层面也支持可视化层面
- WebRTC可实现观察与控制
- 凭证会被安全处理
- 网关可执行审批流程
- 截图可用于提供证据及回放
- 各类生成物会被限定在特定任务范围内
- 清理操作遵循确定的生命周期规则
- 企业身份认证、策略设置及审计机制均已内置
其核心优势可概括为以下几点:
只需演示一次工作流程,之后即可通过任何AI代理来运行它,同时仍可由人类干预并停止后续步骤。
构建过程中的经验教训
浏览器并非最棘手的部分,真正困难的是权限管理。从设计中总结了六点经验教训。
实时视图不仅仅是一个视频播放器,更是一个安全界面:它包含控制功能、审批流程、凭证信息以及用户意图,因此其URL、框架策略、有效期和控制状态都需要像API功能那样得到妥善处理。
仅能传递消息并不等同于完成了交互。虽然用户可能点击了按钮,但页面却可能忽略该操作,正因如此,输入操作需要得到确认反馈,之后还需查看页面状态,并为“已送达”、“已更改”和“仍在等待”设置不同的标识。
盲目重试存在风险。凡是浏览器操作可能带来实际后果的场景,都需要具备幂等性和冲突处理机制。
持久会话既提升了产品的实用性,也同时增加了风险。应通过身份标识对它们进行隔离,并配合注销、数据保留、操作历史记录及清理功能加以管理。
应将页面内容及页面提供的工具视为不可信的。网站虽可描述某项操作,却无权批准它。
最后,有限的证据有助于提升对自动化的信任度。通过截图时间线与操作摘要,用户、开发人员和运维人员都能清晰了解故障原因。
现状与展望
自动化代理需要浏览器,但企业需要的远不止脚本。他们希望拥有一个权责明确的平台,具备有效的权限时效管理、安全的人机交接机制、受保护的登录流程、在产生任何影响前进行审批的功能,以及可监控的结果和可靠的清理机制。
Cloud Browser将Playwright与Chromium整合为这样的平台,实现了规划与执行的分离、代理与凭证的分离,以及浏览器功能与用户权限的分离。正是这种分离使得该设计具有可复用性:更换代理、模型或界面,浏览器周围的安全边界依然保持不变。这是人们真正信任浏览器自动化功能所需的基础。