护栏

护栏是 Bromure Agentic Coding 在宿主机侧对工作区凭据使用方式进行的控制。正如该窗格自身所述:护栏管理此工作区已配置凭据的使用方式。使用前询问会在会话中首次使用某个凭据时弹出宿主机侧的确认。写入策略会在传输过程中剥离或阻止破坏性操作——由代理服务器强制执行,因此虚拟机中被入侵的代理无法绕过它。只有你已配置的凭据才会显示在这里。

工作区设置编辑器的护栏窗格,为每个已配置凭据显示一行,带有使用前询问复选框,并在适用时显示内嵌的写入策略选择器

该窗格为每个已配置凭据显示一行,其顺序与凭据窗格中列出的顺序一致。每一行显示凭据的标题和宿主机,并带有两个控件:

  • 一个使用前询问复选框(控件本身标注为需要批准才能使用)——每个凭据的许可关卡,从凭据窗格移至此处。
  • 一个内嵌的写入策略选择器,仅在凭据对应的服务支持时显示。

如果工作区没有凭据,该窗格会显示空状态——没有可保护的凭据——引导你返回凭据窗格。强制执行细节、错误格式和审计追踪记录在提示注入与护栏深入解析中有介绍。

使用前询问

每一行都有一个使用前询问复选框,默认关闭。当它开启时,在会话中首次使用该凭据时,代理服务器会暂停并弹出一个许可对话框,提供有时限的授权——5 分钟、1 小时,或本会话剩余时间——或不允许。授权仅存于内存中,会在会话窗口关闭时被清除,每个实时决策都会列在**窗口 → 凭据批准…**中。许可模型、并发提示的合并处理以及批准窗口在凭据与传输边界中有介绍。

此复选框适用于任何凭据,包括纯 API 密钥、SSH 密钥和手动令牌——没有写入策略的行只显示此控件。

写入策略

当凭据对应的服务能够对自身流量进行分类时,该行还会显示一个写入策略选择器。它会在以下情况下出现:

  • Git 代码托管平台——GitHub、GitLab、Bitbucket 令牌。
  • AWS 凭据。
  • DigitalOcean 令牌。
  • 容器镜像仓库(Docker Hub、ghcr.io 等)。
  • Kubernetes 上下文。
  • 数据库端点(MongoDB、ClickHouse、Elasticsearch)。

每种写入策略都提供相同的四种模式:

模式行为
关闭不进行过滤。
写入前提示读取操作直接通过。每次写入都会暂停,弹出宿主机侧的许可对话框,显示确切的操作,并提供有时限的授权(见下文)。
阻止破坏性操作删除、drop 和终止操作被阻止;创建和更新操作通过。
只读每次变更都被阻止;只有读取操作通过。

新工作区在每个支持策略的服务上默认使用写入前提示(通过偏好设置模板)。在护栏功能存在之前创建的工作区——或 JSON 中省略了该字段的配置文件——会被解码为关闭

注意: 写入策略是按服务的,而非按凭据。同一服务的两个凭据——比如两个 GitHub 令牌——共享一个策略,因此在任一行更改选择器都会同时更改两者。

注意: 护栏对操作进行分类;它不隐藏凭据。凭据本身仍会按凭据下的配置由代理服务器注入和替换。将只读写入策略与同一行的使用前询问复选框结合使用,可实现纵深防御。

各服务如何对调用进行分类

服务范围分类
Kubernetes来自此工作区 kubeconfig 的 Kubernetes API 服务器GET/HEAD/OPTIONS = 读取;DELETE = 破坏性(包括 deletecollection);其他动词 = 写入。被阻止的调用会返回一个 Kubernetes Status 403 JSON,kubectl 能够清晰地呈现它。
AWS所有 *.amazonaws.com 宿主机来自 X-Amz-Target 请求头的操作名称(如 DynamoDB 和 Lambda 等 JSON 协议服务)或 Action= 表单参数(如 EC2、IAM、SQS 等查询协议服务)按前缀分类:Delete*/Terminate*/Remove*/Purge*/Destroy*/Deregister*/Revoke* = 破坏性;Get*/List*/Describe* 及类似前缀 = 读取。对于 S3 和 REST 风格的请求,则回退到使用 HTTP 方法。被阻止的调用会返回一个 AccessDeniedException 主体。
DigitalOceanapi.digitalocean.com*.digitalocean.comHTTP 方法:DELETE = 破坏性;GET/HEAD = 读取。
容器镜像仓库在凭据下配置的镜像仓库,以及 Docker Hub 端点拉取(GET)= 读取;推送(PUT/POST)= 写入;DELETE = 破坏性。被阻止的调用会返回一个镜像仓库风格的 DENIED 错误主体。
GitHubgithub.com REST API 和基于 HTTPS 的 gitREST 基于方法。git pushgit-receive-pack)算作写入——在只读下被阻止,在写入前提示下会提示;git fetchgit-upload-pack)始终为读取。
GitLabgitlab.com REST API 和基于 HTTPS 的 git与 GitHub 相同的分类逻辑。
Bitbucketbitbucket.org REST API 和基于 HTTPS 的 git与 GitHub 相同的分类逻辑。

数据库端点按引擎进行分类:

引擎读取写入破坏性
MongoDB (Atlas Data API)findfindOneaggregateinsertupdatereplacedeleteOnedeleteMany
ClickHouseSELECTSHOWDESCRIBEEXPLAINWITH 等为首关键字的 SQL …INSERTCREATEALTERDROPTRUNCATEDELETE,以及 ALTER … DELETE / DROP COLUMN / DROP PARTITION / CLEAR
Elasticsearch_search_msearch_count_mget_sql 以及其他查询端点(即使通过 POST_bulk_update、文档索引DELETE_delete_by_query

当设置了某个策略但没有可供其应用范围的对象时——Kubernetes 上下文没有 kubeconfig、数据库端点没有设置宿主机——会出现橙色内嵌警告,因为此时护栏没有可应用的宿主机。

注意: 对于 ClickHouse,如果请求中看不到 SQL 文本,只读会阻止该请求(Bromure 无法证明它是读取),而阻止破坏性操作会放行(它采取放行的默认策略)。

许可对话框(写入前提示)

写入前提示模式下,读取操作静默通过,每次写入都会暂停并弹出一个标题为 Allow write on "<scope>" from workspace "<name>"? 的宿主机对话框。对话框主体逐字显示确切的操作——数据库的字面 SQL 语句,或 REST 调用的 METHOD /path——因此你批准的是实际将要运行的内容,而非摘要。按钮包括:

  • 允许 15 分钟(默认按钮)
  • 允许一次——刻意不创建任何授权,因此紧接着的下一次写入会重新提示。适用于对一个话痨的代理逐次写入进行审计。
  • 允许本会话剩余时间
  • 不允许——代理会收到与阻止模式所产生的相同的硬错误。该拒绝会被记住 60 秒,这样循环重试同一次写入的代理不会每秒都重新提示。

授权按工作区和协议范围划定:一个 Kubernetes API 宿主机、整个 AWS、一个容器镜像仓库、每个 git 代码托管平台整体,或一个数据库宿主机。在一个宿主机上允许 ClickHouse 写入不会在其他任何地方授予任何权限。并发的相同写入会合并到单个对话框上,所有决策仅存于内存中——会话范围的授权会在会话拆除时被清除。

当工作区通过 SSH 或 CLI 以无界面方式驱动时,相同的四个选项会作为文本提示出现在工作区的 tmux 中;不回答即视为拒绝。

注意: 护栏的写入授权不会列在任何窗口中。凭据批准窗口(窗口菜单 → 凭据批准…)仅显示凭据许可决策——即使用前询问的授权;写入策略授权会按其自身的时钟或在会话拆除时到期。

调用被阻止时代理看到的内容

被阻止的调用会返回一个协议相应的 403 风格错误主体——Kubernetes Status JSON、AWS AccessDeniedException、镜像仓库 DENIED 载荷——其消息以 "blocked by Bromure Guardrails" 结尾。代理看到的是一个可以报告的干净、普通的 API 失败,而非一个挂起的连接。(供应链阻止改用 HTTP 451,正是为了让两者一眼就能区分——见供应链。)

局限性

  • Git 强制推送在传输过程中无法与普通推送区分开来,因此阻止破坏性操作不会阻止它——只有只读写入前提示会对推送进行关卡控制。通过代码托管平台 REST API 进行的显式删除仍会被捕获。
  • Kubernetes 和容器镜像仓库策略仅应用于从工作区 kubeconfig 和已配置镜像仓库派生的宿主机;数据库策略需要在凭据下设置端点的宿主机。没有可应用范围对象的护栏不会过滤任何内容(该窗格会内嵌警告你)。
  • 护栏涵盖上面列出的服务。发往其他宿主机的任意 HTTPS 流量不会被分类——软件包下载见供应链,代理的 AI 流量见提示注入