护栏
护栏控制一台机器的凭据可以怎么被使用(机器在设置编辑器中即工作区)、代理碰壁或行为异常时机器如何反应,以及它的流量被拦截得多严。它的 VM 可以开哪些连接,则在沙盒策略中设置。用窗格自己的话说:“护栏统管这个工作区已配置凭据的使用方式。使用前先问会在某个凭据于一个会话中首次被使用时,弹出一则主机端的确认。写入策略在传输上剥除或挡下破坏性操作——在代理服务器中执行,所以被入侵的代理绕不过去。这里只会出现你配置过的凭据。”
这个窗格有两个部分:每个凭据一行,接着是防护——两种沙盒引擎共用的设置。(以前放在这里的出站连接规则,在 5.4 移到了沙盒策略。)其中的一切都会在你点击存储时套用到运行中的机器——不需重新启动。更深的机制在提示注入检测与护栏。
凭据的各行
窗格会依同样的顺序列出在凭据中配置的每一个凭据。每一行显示该凭据的名称与主机、一个使用需经批准复选框,以及——在服务支持的情况下——一个写入策略选择器。没有凭据时,窗格会显示没有要看守的凭据,并指引你到凭据窗格。
使用需经批准(使用前先问)
默认关闭。开启后,该凭据在一个会话中首次被使用时,代理服务器会把请求暂停并询问,提供允许 5 分钟、允许 1 小时、这个会话的其余时间都允许或不允许。授予只存在内存中,随会话结束;**窗口 › 凭据批准…**会列出目前的授予。见凭据与传输边界。
当凭据有生效中的授予时,它那一行会在复选框旁显示剩余时间——限时授予显示橙色倒计时(4m,然后 45s),整个会话的授予显示本会话已允许,拒绝生效期间则显示红色的已拒绝倒计时(或本会话已拒绝)。在该行上右键即可选择允许 5 分钟、允许 1 小时或这个会话的其余时间都允许,拒绝 5 分钟、拒绝 1 小时或这个会话的其余时间都拒绝(不询问直接拒绝),或撤销——下次再询问以清除两者,让下一次使用重新提示。限时的允许或拒绝从现在起算,所以快到期的授予会重新获得 5 分钟。这些操作会立即作用于运行中的会话,无需保存。(倒计时只出现在运行该工作区的 Mac 上、该工作区自己的设置中,不会出现在偏好设置或远程客户端。)
注意: 使用了开着批准的凭据的自动化,无法完全无人运行:它会停在对话框上,直到你在 Mac 上作答。自动化编辑器会就此提出警告。
写入策略
写入策略选择器会出现在:
- git 代管平台的令牌(GitHub、GitLab、Bitbucket)
- AWS 凭据
- DigitalOcean 令牌
- 容器注册表
- Kubernetes 环境
- 数据库端点(MongoDB、ClickHouse、Elasticsearch)
| 模式 | 行为 |
|---|---|
| 关闭 | 不做过滤。 |
| 写入前先问 | 读取通过。每一次写入都会停下,出现一个显示确切操作的对话框。 |
| 挡下破坏性操作 | 删除、丢弃与终止会被挡下;创建与更新通过。 |
| 只读 | 任何更改都被挡下;只有读取通过。 |
新机器对每一种服务都使用写入前先问(来自默认值模板)。在护栏存在之前创建的机器会以关闭载入。
注意: 写入策略是按服务而非按凭据的,一如窗格所注:“同一种服务的两个凭据(例如两个 GitHub 令牌)共用一份策略。”改其中任一行就会同时改到两者。
每种服务如何被归类
| 服务 | 范围 | 归类 |
|---|---|---|
| Kubernetes | 这台机器 kubeconfig 中的各个 API 服务器 | GET/HEAD/OPTIONS 为读取;DELETE(包含 deletecollection)为破坏性;其他动词为写入。被挡下的调用会返回一个 Kubernetes 的 Status 403,kubectl 会清楚地显示它。 |
| AWS | *.amazonaws.com | 依前缀看动作名称(X-Amz-Target 标头或 Action= 参数):Delete*、Terminate*、Remove*、Purge*、Destroy*、Deregister*、Revoke* 为破坏性;Get*、List*、Describe* 之类为读取。S3 与 REST 风格的调用退回看 HTTP 方法。被挡下的调用会返回 AccessDeniedException。 |
| DigitalOcean | *.digitalocean.com | DELETE 为破坏性;GET/HEAD 为读取。 |
| 容器注册表 | 已配置的注册表与 Docker Hub | 拉取为读取;推送为写入;DELETE 为破坏性。被挡下的调用会返回注册表的 DENIED 错误。 |
| GitHub / GitLab / Bitbucket | 该平台的 REST API 与走 HTTPS 的 git | REST 依方法判断。git push 是写入(在只读下被挡,在写入前先问下会询问);git fetch 永远是读取。 |
数据库端点依引擎归类:
| 引擎 | 读取 | 写入 | 破坏性 |
|---|---|---|---|
| MongoDB(Atlas Data API) | find、findOne、aggregate | insert、update、replace | deleteOne、deleteMany |
| ClickHouse | SELECT、SHOW、DESCRIBE、EXPLAIN、WITH … | INSERT、CREATE、ALTER … | DROP、TRUNCATE、DELETE,以及 ALTER … DELETE / DROP COLUMN / DROP PARTITION / CLEAR |
| Elasticsearch | _search、_msearch、_count、_mget、_sql 与其他查询(即使走 POST) | _bulk、_update、建立索引 | DELETE、_delete_by_query |
当某份策略没有可套用的对象时,会出现一则橙色警告——例如没有 kubeconfig 的 Kubernetes 环境,或没有主机的数据库端点。
注意: 对 ClickHouse 来说,若请求里看不到 SQL 文字,只读会挡下它(无法证明那是读取),而挡下破坏性操作会让它通过。
写入对话框
在写入前先问下,一次写入会停下并出现要允许从工作区“名称”对“范围”写入吗?,把操作原封不动显示出来——那道 SQL 语句,或 方法 /路径。选项有:
- 允许 15 分钟(默认)
- 允许一次——不建立授予,所以下一次写入还会再问。
- 这个会话的其余时间都允许
- 不允许——代理会收到跟那些会挡下的模式相同的错误。这个拒绝会被记住 60 秒,好让重试循环不必每秒都再问一次。
授予是按机器、按范围的:一个 Kubernetes API 服务器、AWS 整体、一个注册表、每个代管平台,或一台数据库主机。同时发生的相同写入共用一个对话框。当机器透过 SSH 或 CLI 以无界面方式使用时,同样的选项会在机器的 tmux 里被问;不作答就等于拒绝。
不对凭据外泄发出警报
当某个凭据被看见正前往一台它不属于的主机时,Bromure 会挡下该请求、把 VM 挂起,并显示一则入侵警报,带着关机、封锁、允许与保存以供调查。允许会在该会话的其余时间信任那个目的地。见凭据与传输边界。
不对凭据外泄发出警报会为这台机器关掉那则警报。外泄仍然被挡下,也仍然记录在安全时间线中,记为“已封锁 — 外泄尝试(警报已关,VM 未挂起)”——消失的只有那次中断。即时生效,不需重新启动。默认:关闭。
防护
防护分区收纳的设置,不论机器用的是哪一种沙盒引擎都适用。每一项都会立即应用到运行中的机器。
策略拦截时告知代理
Tell the agent when policy blocks it——“代理会来问你,而不是重试或另找门路”。当防火墙、OpenShell 策略、客户机沙盒或某道护栏拒绝了代理尝试的事,代理会被告知拦截了什么、为什么,并被要求来问你,而不是重试或另找门路。没有这个设置时,代理只看到一条失败的连接或“permission denied”,可能会一直试下去。Claude Code 会在碰到拦截的那条命令之后立刻读到这则通知。Codex、Grok、Kimi 与 Oh My Pi 则在它们的回合结束时收到输入的通知。在你做出选择之前,只要机器使用 OpenShell 策略,它就是开启的。请参阅告知代理。
代理看门狗
Agent watchdog——“标记行为可疑的会话;Quarantine 还会切断它的网络并将它暂停”。看门狗从 VM 外部,把会话当成一个整体来监看:
- 一连串被拦截的请求;
- 不属于这里的凭据;
- 篡改的迹象;
- 会话稳定下来之后出现的新目的地;
- 远高于会话自身基线的出站流量(在网络交换机上统计,与代理无关)。
| 模式 | 会话在一分钟内的分数超过阈值时 |
|---|---|
| Off(默认) | 什么都不做。 |
| Alert | 在安全时间线中留下一行 Agent watchdog(“drift detected”),在已注册的 Mac 上也会发送给你的组织。 |
| Quarantine | VM 的网络在几毫秒内被切断,VM 也被暂停。接着一则警报 The agent watchdog quarantined this workspace 会列出它看到了什么。关机 会停止机器;Keep quarantined 让它在网络仍被切断的情况下继续运行,好让你进去查看;Release 会恢复网络。 |
当警报无法在这台 Mac 上显示时(无头的 Mac,或由远程客户端镜像的机器),问题会发送到远程客户端,三分钟内没有回答则视为 Keep quarantined。
只允许 Bromure 注入的凭据(严格模式)
Only allow credentials Bromure injects (strict mode)——“拦截任何不是 Bromure 自己放进去的凭据”。开启严格模式后,带着 Bromure 没有注入的凭据的请求会被拦截,并触发入侵警报;这涵盖代理在文件里找到、从日志复制或自行带来的密钥。在警报中点击允许,会在这个会话中批准该凭据。网站在 VM 内签发的令牌(例如登录后的会话 Cookie)仍可发回那个网站。
严格模式会强制透明拦截,并忽略不拦截列表。原始 TCP 流量无法检查。机器配置的每个凭据都必须先有主机过滤条件;窗格会点名没有的那些。默认关闭;你的组织可以要求开启。
停用透明拦截
默认情况下,虚拟交换机会在网络层把 VM 的 HTTP 与 HTTPS 连接(端口 80 与 443)改道进 Bromure 的代理服务器,所以即使某支程序忽略代理设置,代理服务器也看得到它们。
开启停用透明拦截只会停掉那道强制改道。开启原始连接的程序,以及固定证书(certificate pinning)的应用程序,这时就会直接连上网络——以及真正的服务器证书。代理服务器本身仍然开着:HTTP_PROXY / HTTPS_PROXY 依旧设置着,所以懂得用代理的工具(apt、git、pip、curl、node…)与代理自己的 API 调用,仍然会走过 Bromure,并保有凭据替换、追踪与护栏。即时生效,不需重新启动。严格模式开启时无法使用。
把它用在某台机器上,若它有个客户端在拦截之下就坏掉。在它开启期间,那些绕过代理设置的程序的流量,既不被防火墙的 web 规则看到,也不被写入策略看到。
允许逐请求的不安全绕道(X-bromure-insecure)
为自签或私有 CA 的服务器准备的一道更窄的逃生门。当送往这种主机的请求在证书验证上失败时,代理可以带上 X-bromure-insecure: yes 标头重试,而 Bromure 就会在那一次请求中略过验证该服务器的证书。拦截、追踪与外泄守卫仍然开着,而 Bromure 不会把任何真正的凭据放进这样的请求里——出去的只有 VM 的替身。每一次使用都会记录在安全时间线中。
默认开启:它只在 VM 明确送出那个标头时才作用。把它关掉就会直接拒绝那个标头。
调用被挡下时代理看到什么
被挡下的调用会以该服务自己的格式返回一个普通的错误——Kubernetes 的 Status、AWS 的 AccessDeniedException、注册表的 DENIED——而它的消息以“blocked by Bromure Guardrails”结尾。代理看到的是一次可以汇报的干净失败,而不是一条挂住的连接。(供应链的封锁改用 HTTP 451,所以两者很容易分辨——见供应链。)
限制
- force-push 在传输上看起来就像一次普通的 push,所以挡下破坏性操作拦不住它;只读与写入前先问确实会为 push 设下关卡。经由该平台 REST API 的删除则会被捕捉到。
- Kubernetes 与注册表的策略只涵盖来自这台机器 kubeconfig 与注册表的主机;数据库策略需要那个端点的主机。
- 其他主机由沙盒策略的主机、端口与方法规则管辖,而不是由服务层级的分类管辖。
设置参考
| 设置 | 类型 | 默认 |
|---|---|---|
| 使用需经批准 | 每个凭据一个复选框 | 关闭 |
| 写入策略 | 每种服务各自:关闭 / 写入前先问 / 挡下破坏性操作 / 只读 | 新机器为写入前先问 |
| 不对凭据外泄发出警报 | 开关 | 关闭 |
| Tell the agent when policy blocks it | 开关 | 机器使用 OpenShell 策略时开启 |
| Agent watchdog | Off / Alert / Quarantine | Off |
| Only allow credentials Bromure injects (strict mode) | 开关 | 关闭 |
| 停用透明拦截 | 开关 | 关闭 |
| 允许逐请求的不安全绕道(X-bromure-insecure) | 开关 | 开启 |