防護欄
防護欄是 Bromure Agentic Coding 在主機端對工作區憑證使用方式的控管機制。正如此窗格本身所述:防護欄用於管控此工作區所設定憑證的使用方式。使用前詢問會在某憑證於工作階段中首次被使用時,於主機端彈出確認對話框。寫入政策則會在傳輸過程中剝除或封鎖破壞性操作——由代理伺服器強制執行,因此 VM 內遭入侵的代理程式無法繞過它。此處只會顯示你已設定的憑證。
此窗格每個已設定的憑證顯示一列,順序與憑證窗格列出的順序相同。每一列會顯示該憑證的標題與主機,並附有兩項控制項:
- 一個使用前詢問核取方塊(在控制項本身標示為需經核准才能使用)——各憑證專屬的同意閘門,已從憑證窗格移至此處。
- 一個內嵌的寫入政策選擇器,僅在該憑證的服務支援時顯示。
若工作區沒有任何憑證,此窗格會顯示空白狀態——沒有可防護的憑證——引導你回到憑證窗格。強制執行細節、錯誤格式與稽核軌跡,請見提示注入與防護欄深入解析。
使用前詢問
每一列都有一個使用前詢問核取方塊,預設為關閉。啟用後,該憑證於工作階段中首次被使用時,代理伺服器會暫停並彈出同意對話框,提供有時限的授權——5 分鐘、1 小時,或本工作階段剩餘時間——或選擇不允許。授權僅存於記憶體中,並在工作階段視窗關閉時清除,而每一項即時決定都會列於 Window → Credential Approvals…。同意模型、並行提示的合併,以及核准視窗,皆於憑證與傳輸邊界中說明。
此核取方塊適用於任何憑證,包括純 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 標頭的動作名稱(JSON 協定服務,如 DynamoDB 與 Lambda)或 Action= 表單參數(查詢協定服務,如 EC2、IAM、SQS),依前綴分類:Delete*/Terminate*/Remove*/Purge*/Destroy*/Deregister*/Revoke* = 破壞性;Get*/List*/Describe* 及類似者 = 讀取。對 S3 與 REST 樣式的請求則回退至 HTTP 方法判斷。遭封鎖的呼叫會回傳 AccessDeniedException 主體。 |
| DigitalOcean | api.digitalocean.com 與 *.digitalocean.com | HTTP 方法:DELETE = 破壞性;GET/HEAD = 讀取。 |
| 容器登錄檔 | 在憑證下設定的登錄檔,以及 Docker Hub 端點 | 拉取(GET)= 讀取;推送(PUT/POST)= 寫入;DELETE = 破壞性。遭封鎖的呼叫會回傳登錄檔樣式的 DENIED 錯誤主體。 |
| GitHub | github.com REST API 及透過 HTTPS 的 git | REST 依方法判斷。git push(git-receive-pack)算作寫入——在唯讀下遭封鎖,在寫入前詢問下會提示;git fetch(git-upload-pack)一律為讀取。 |
| GitLab | gitlab.com REST API 及透過 HTTPS 的 git | 分類邏輯與 GitHub 相同。 |
| Bitbucket | bitbucket.org REST API 及透過 HTTPS 的 git | 分類邏輯與 GitHub 相同。 |
資料庫端點依引擎分類:
| 引擎 | 讀取 | 寫入 | 破壞性 |
|---|---|---|---|
| MongoDB(Atlas Data API) | find、findOne、aggregate | insert、update、replace | deleteOne、deleteMany |
| ClickHouse | 前導關鍵字為 SELECT、SHOW、DESCRIBE、EXPLAIN、WITH … 的 SQL | 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 |
當政策已設定但沒有可套用的範圍時——某 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 內以文字提示形式提供相同的四個選項;不作答即視為拒絕。
附註: 防護欄的寫入授權不會列於任何視窗中。Credential Approvals 視窗(Window 選單 → Credential Approvals…)僅顯示憑證同意決定——即使用前詢問授權;寫入政策授權會依其自身時鐘或在工作階段拆除時到期。
呼叫遭封鎖時代理程式看到的內容
遭封鎖的呼叫會回傳與協定相符的 403 樣式錯誤主體——Kubernetes Status JSON、AWS AccessDeniedException、登錄檔 DENIED 酬載——其訊息結尾為「blocked by Bromure Guardrails」。代理程式看到的是一個乾淨、普通、可回報的 API 失敗,而非懸而未決的連線。(供應鏈封鎖改用 HTTP 451,正是為了讓兩者能一眼區分——見供應鏈。)