憑證與傳輸邊界
一個代理式編碼工作階段需要憑證——用來與 Claude 對話的 Anthropic 金鑰、用來推送的 GitHub 權杖、用來部署的 AWS 金鑰。它同時也會執行任意程式碼、安裝任意套件,並遵循它並未撰寫的檔案中的指示。把你真正的密鑰交給這樣的環境,正是金鑰最終落入竊取者收件匣的原因。
Bromure Agentic Coding 以傳輸邊界化解這個矛盾:VM 內部的代理程式永遠只會看見偽造的佔位權杖。你真正的憑證以加密形式存放在 macOS 主機上,並由主機端的 MITM 代理伺服器在最後一刻——在請求離開 VM 之後、且僅當請求送往該憑證所屬的主機時——替換到傳輸線路上。VM 內部沒有任何檔案、環境變數或行程會包含真正的 API 金鑰、OAuth 權杖、AWS 密鑰或 SSH 私鑰。
本章先從頭到尾說明其機制,接著逐一介紹代理程式如何登入、每種支援的憑證類型及其生命週期、逐次使用的核准系統、入侵偵測器、在攔截下無法運作之主機的應急做法,以及如何自行驗證這道邊界。
憑證依機器設定。機器就是設定編輯器仍稱為工作區的東西;兩個詞指的是同一台 VM 及其設定。
附註: 本章涵蓋概念與執行時的行為。設定窗格的逐欄參考,請參閱設定 → 憑證。代理程式的 API 金鑰與訂閱不再於該窗格中設定;它們位於 偏好設定 › 模型(請參閱模型與供應商)。
傳輸邊界一覽
三項原則定義了此模型:
- VM 內是偽造值。 你設定的每一個憑證,在 VM 內部都會被一個保留結構的偽造值取代。偽造值維持驗證器所預期的形狀——Anthropic 偽造值以
sk-ant-api03-brm-開頭,GitHub 偽造值是ghp_加上 36 個字元——因此像claude、gh和doctl這類工具都會毫無異議地接受它們。 - 真值只存在於傳輸線路上。 VM 發出的每一個 HTTPS 請求都會通道傳送到主機代理伺服器,由它解密、將偽造值換成真值,再重新加密後往上游傳送。此替換的範圍侷限於該憑證所產生的目的地主機。
- 失敗即封閉。 如果有任何東西繞過了代理伺服器,該請求只會攜帶偽造值,上游驗證便會失敗。不存在任何會意外洩漏真正密鑰的路徑。
偽造值是確定性的:每一個偽造值都是透過 HKDF-SHA256,從真值加上一個各安裝專屬的 32 位元組鹽值衍生而來。同一把真正的金鑰在你的 Mac 上永遠對應到同一個偽造值,因此那些會對其金鑰做指紋辨識的用戶端(例如 Claude Code 會快取金鑰雜湊)永遠不會看到憑證在各工作階段之間「輪替」。
| 憑證 | VM 內的偽造值形狀 |
|---|---|
| Anthropic API 金鑰 | sk-ant-api03-brm-… |
| OpenAI API 金鑰 | sk-brm-… |
| xAI API 金鑰 | xai-brm-… |
| Moonshot(Kimi)API 金鑰 | sk-kimi-brm-… |
| Claude Code 使用的 OpenRouter 金鑰 | sk-or-v1-brm-… |
| Amazon Bedrock API 金鑰 | bedrock-brm-… |
| GitHub 權杖 | ghp_ + 36 個字元(共 40 個) |
| GitLab 權杖 | glpat- + 20 個字元 |
| DigitalOcean PAT | dop_v1_ + 十六進位(共 64 個字元) |
| Linear API 金鑰 | lin_api_ + 40 個字元(共 48 個) |
| Twilio 驗證權杖/API 金鑰機密 | brm-twilio-…(至少 32 個字元) |
| MCP bearer 權杖 | brm-mcp_… |
| Docker 登錄密碼 | brm-docker-…(至少 40 個字元) |
| Kubernetes bearer 權杖 | brm-k8s-… |
| 資料庫密鑰 | brm-db-…(至少 32 個字元) |
| 通用手動權杖 | brm_… |
此邊界並沒有開關。代理伺服器是 VM 唯一的出口路徑;替換就是本應用程式中憑證運作的方式。
替換如何從頭到尾運作
一個經過驗證的請求的完整往返:
- 工作階段啟動——權杖計畫。 機器的 VM 啟動時,應用程式會建立每台機器專屬的權杖計畫,把每個真正的憑證與其衍生的假值配對。假值會寫入 VM:環境變數(
ANTHROPIC_API_KEY、GH_TOKEN、LINEAR_API_KEY、…)與設定檔(~/.git-credentials、~/.docker/config.json、~/.kube/config、~/.aws/config、~/.config/doctl/config.yaml、MCP 設定)。真值則載入代理伺服器記憶體中的替換對照表,各自綁定到所屬的目的地主機。 - 請求離開 VM。 客體的 HTTPS 流量透過一個 virtio socket(vsock 連接埠 8443)通道傳送到主機代理伺服器。VM 沒有其他通往網路的路由。
- TLS 終止。 代理伺服器出示一張偽造的各主機專屬葉憑證——以目的地主機名稱作為 CN 與 SAN、一把各主機專屬的 EC 金鑰——由 Bromure Agentic Coding Root CA 簽署。由於該 CA 的公開憑證在開機時就已安裝進 VM 的信任存放區,客體的 TLS 用戶端便會接受此連線,代理伺服器也就能讀取明文請求。
- 替換。 代理伺服器查找請求中出現的每一個偽造權杖(標頭,以及對於選擇加入的憑證類型還包括本文),若目的地主機符合該憑證的範圍,便將其替換為真值。
- 往上游重新加密。 改寫後的請求透過 Apple 的
URLSession(即 macOS 本身的 TLS 堆疊)重新發送至真正的目的地,該堆疊會驗證上游伺服器的真實憑證。回應則透過通道串流回客體。
若目的地不符合某個偽造值的範圍,該偽造值會原封不動地送出(並在上游驗證時失敗)——或者,當此不符看起來像是外洩時,該請求會被直接封鎖(見下方入侵偵測器)。
Bromure Agentic Coding Root CA
此 CA 為各安裝專屬,存放於 ~/Library/Application Support/BromureAC/ca/(cert.pem 加上一個模式為 0600 的 key.pem)。其主體為「Bromure Agentic Coding Root CA」,組織為「Bromure」。值得了解的屬性:
- CA 效期為 10 年。偽造的各主機專屬葉憑證效期為 1 年,並回溯 24 小時,因此一個在暫停/恢復期間時鐘偏移的客體仍會接受它們。葉憑證會依主機快取,存續於應用程式行程的生命週期內。
- 該公開憑證在開機時被安裝進每一個 VM 的信任存放區(透過 meta 共用傳遞,並以
update-ca-certificates套用)。它永遠不會離開你的機器,除了你的 VM 之外沒有任何東西信任它。 - 若要輪替 CA,請結束應用程式並刪除
ca/目錄。下次啟動時會產生一個全新的 CA,每個 VM 會在其下次開機時取得新的公開憑證。輪替不會使其他任何東西失效——工作區密鑰與profile.json中繼資料都不受影響。
主機範圍界定
每一筆替換項目都繫結至一個主機範圍。比對採完全相符或子網域,且不分大小寫,絕不做子字串比對:一個範圍界定為 openai.com 的憑證會比對到 api.openai.com,但不會比對到 openai.com.evil.example——一個看起來相似的主機無法騙過代理伺服器,讓它在其請求上添加真正的金鑰。手動權杖規則可以刻意使用空白的主機篩選,意即「在任何主機上都注入」;這是你為每一項項目所做的明確選擇(見通用 API 金鑰)。
依設計即失敗封閉
此設計從不依賴代理伺服器不可繞過來達成保密——它依賴的是密鑰根本不在那裡:
- 一個以某種方式跳過代理伺服器的請求會攜帶偽造權杖;上游 API 會拒絕它。
- 在 VM 內部簽署的 AWS 請求是以偽造的密鑰簽署的;若它們直接抵達 AWS 便會以
InvalidSignatureException失敗(見下方 AWS)。 - SSH 私鑰的位元組根本從不存在於 VM 中;只有簽章會跨越此邊界。
在工作區編輯器中管理憑證
服務憑證——git 權杖、雲端金鑰、登錄庫、資料庫、SSH 金鑰——依機器設定。開啟機器的設定(機器選單中的 設定…,或工作階段選單中的 「機器」設定…),然後在側邊欄的 安全性 之下選擇 憑證。
窗格一開頭是 Git 身份(寫入 VM 中 ~/.gitconfig 的姓名與電子郵件;兩者皆留空可保留 git 的預設值——預留文字只是範例,不是憑證),接著是只列出你已設定之憑證的清單,依類別標題分組(Agents、Git、Cloud、Databases、SSH、Other)。尚未設定任何東西時,窗格會顯示 尚無憑證。底部有兩個按鈕:新增憑證 會開啟憑證類型選擇器——Git token、SSH key、AWS credentials、DigitalOcean token、Linear API key、Twilio API key、Kubernetes、Container registry、Database 與 Other API key——而 匯入 env 檔案… 則從 .env 或 ~/.bashrc 大量匯入。點按 儲存;下次啟動工作階段時,會把假值寫入 VM,並把真值載入代理伺服器。
代理程式的 API 金鑰(Anthropic、OpenAI、xAI、Moonshot 及其他模型供應商)不在此選擇器中:它們在接下來介紹的 偏好設定 › 模型 中設定。Agents 群組只會出現在仍保存著舊版遺留之專屬代理程式金鑰的工作區上;其 在「模型」中編輯… 選單項目會開啟 偏好設定 › 模型。若要變更模型存取,請使用 偏好設定 › 模型 或機器的 模型 窗格。
每個憑證的核准關卡(使用前詢問)與各服務的寫入政策是在防護欄窗格中設定,而不是在這裡。逐欄參考請參閱設定 → 憑證。
有七個供應商會自動處理——Anthropic、OpenAI、GitHub、GitLab、DigitalOcean、Twilio 與 Kubernetes 不需要手動權杖規則;它們各自的章節會說明。其他一切都透過其他 API 金鑰處理。
從 env 檔案匯入。 匯入 env 檔案… 會讀取既有的 .env 檔案——或 ~/.bashrc——並把其中的變數轉成憑證。剖析器能處理 KEY=VALUE 與 export KEY=VALUE,去除外圍引號與行尾註解,並刻意略過任何需要 shell 求值的內容($VAR 插值或 $(…) 取代),因此指向真正的 .bashrc 也很安全。接著,檢閱表單會以遮蔽的值顯示這些變數:已辨識的名稱(GH_TOKEN/GITHUB_TOKEN、GITLAB_TOKEN、AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN、DIGITALOCEAN_ACCESS_TOKEN、LINEAR_API_KEY、TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN,以及模型供應商金鑰 ANTHROPIC_API_KEY、OPENAI_API_KEY、XAI_API_KEY、MOONSHOT_API_KEY 與 KIMI_API_KEY,後者會進入 偏好設定 › 模型 中對應的供應商——若是遠端機器,則進入其自己的 模型 覆寫)會自動對應到其憑證類型,而未辨識的名稱可以匯入為通用手動權杖,並附上你提供、以逗號分隔的主機範圍。已設定的項目會被標記並保持未勾選,因此重新匯入絕不會悄悄覆寫機密。
代理程式金鑰與訂閱
每個程式設計代理程式——Claude Code、Codex、Grok、Kimi 與 omp——都從 偏好設定 › 模型(⌘, 後選擇 模型)中設定的供應商取得模型存取權。每台機器的設定中也有同樣的窗格,作為選用的機器專屬覆寫。完整參考——供應商、各代理程式的模型選擇、機器專屬覆寫、OpenRouter、自訂伺服器與裝置端模型——請見模型與供應商。本節說明與憑證相關的重點:金鑰或訂閱如何在不進入 VM 的情況下送達代理程式。
在 供應商 欄中點按一個供應商即可開啟其彈出視窗。每個供應商的彈出視窗都有 API 金鑰 欄位;提供訂閱的四個供應商還會有登入控制項。
API 金鑰
把金鑰貼到彈出視窗的 API 金鑰 欄位。在偏好設定中,窗格會隨著輸入即時儲存;在機器的設定中,金鑰以 儲存 儲存。生命週期:
- 在 VM 中: 代理程式慣用的變數(
ANTHROPIC_API_KEY、OPENAI_API_KEY、XAI_API_KEY、…)存放著符合供應商格式的假值(sk-ant-api03-brm-…、sk-brm-…、xai-brm-…、sk-kimi-brm-…)。 - 在傳輸途中: 只有在送往該供應商主機(
anthropic.com、openai.com、x.ai、moonshot.ai、…)的請求中,才會換成真正的金鑰。 - 靜態保存: 金鑰與模型設定的其餘部分一樣,加密保存在
models.enc中(請參閱機密在主機上的存放位置)。
在 模型 中設定的金鑰不會出現在憑證或防護欄窗格中,因此沒有 使用前詢問 列。(舊版遺留、仍存放在工作區本身的代理程式金鑰則會出現在那裡,也可以設定核准。匯入 env 檔案已不會再建立這類金鑰:它會把代理程式金鑰放進模型設定。)
從 CLI,bromure-cli workspaces create --auth token|subscription|bedrock|local 與 bromure-cli vm run --auth token|subscription|bedrock|local 仍會選擇工作區主要代理程式的驗證模式。
訂閱:Claude、ChatGPT、Grok 與 Kimi
如果你有的是訂閱而不是 API 金鑰,請改為登入。訂閱只適用於 Anthropic (Claude)、OpenAI(ChatGPT,由 Codex 使用)、xAI (Grok) 與 Moonshot (Kimi);z.ai、Amazon Bedrock、OpenRouter 與自訂伺服器只接受金鑰,omp 則只支援 API 金鑰。訂閱只驅動它自己的代理程式:Claude 登入執行 Claude Code,ChatGPT 登入執行 Codex,依此類推。
無論以何種方式登入,結果都一樣:真正的 OAuth 權杖只存在於主機上,而客體以一把假金鑰執行——Claude 是一個假的 ANTHROPIC_API_KEY,Codex 是一個預先填入、內含到期日極遠之假 JWT 的 ~/.codex/auth.json(讓用戶端永遠不會嘗試更新它),Grok 與 Kimi 則是在它們各自憑證檔案中的替代權杖。代理伺服器會辨識出這個假值,並在傳輸途中注入有效的 Authorization: Bearer 存取權杖。
從偏好設定 › 模型登入
供應商的彈出視窗會顯示三種狀態之一:
| 狀態 | 彈出視窗顯示的內容 |
|---|---|
| 未登入 | Sign in with 供應商、「在暫時的虛擬機器中互動式登入——不需要 API 金鑰。」,接著在 API 金鑰 欄位上方顯示「或貼上 API 金鑰」。 |
| 已登入 | 一行綠色的「已登入」並附上登入日期,以及 重新登入… 與 登出…。 |
| 已過期 | 一個橘色的 登入已過期 面板——「供應商 拒絕了已儲存的登入(…)。在你重新登入之前,工作階段無法使用它。」——附有 重新登入 與 登出…。 |
Sign in with 供應商 會執行註冊流程:
- 標題為 向 供應商 註冊 的說明會告訴你接下來會發生什麼。點按 繼續。(若 Bromure 代理伺服器沒有在執行,註冊會被拒絕。)
- 一台用完即丟的註冊 VM 會啟動——暫時、隔離,沒有工作區檔案夾、沒有已儲存的機密,也沒有憑證替換對照表。代理程式自己的登入指令會在其中執行。
- 你 Mac 的預設瀏覽器會開啟供應商的登入頁面。照常登入即可。
- 取得的權杖會在主機上擷取、加密並儲存;用完即丟的 VM 會關機並刪除。
從偏好設定開始的登入一律由所有機器共用。登出… 會詢問「要登出 供應商 嗎?」——「使用此登入的工作區將停止運作,直到你重新登入。」——並刪除已儲存的登入。在無法作用的地方,登出… 會隱藏。
從機器的模型窗格登入:共用範圍
同樣的彈出視窗也會出現在機器自己的 模型 窗格中。在那裡開始的登入最後會詢問一個問題:要與每個工作區共用嗎?:
| 按鈕 | 效果 |
|---|---|
| 每個工作區 | 把此登入儲存為共用登入,並且移除每台機器對該供應商的專屬登入,讓每台機器確實使用新的登入。 |
| 僅此工作區 | 只為這台機器儲存此登入。 |
範圍之所以重要,是因為機器會先讀取自己的登入,只有在沒有時才退而使用共用登入。曾經為自己登入過的機器會一直使用那個登入,即使之後有更新的共用登入也一樣,直到你選擇 每個工作區 或讓那台機器登出為止。開始登入的遠端用戶端也會收到同樣的問題;若沒有人回答,登入就只屬於那台機器。
從聊天登入
你不必先到偏好設定。當工作階段中的代理程式需要登入時,聊天會顯示一張標題為 登入 供應商 的卡片——「Bromure 在此 Mac 上為你登入,並讓你的 供應商 帳號遠離機器 — 代理程式只會看到一個替身金鑰。」——附有 登入 供應商… 按鈕,而側邊欄中該工作階段的列會顯示 需要登入。當代理程式已儲存的登入遭到拒絕時,紅色錯誤卡片也會提供同樣的按鈕。
點按它就能在不使用用完即丟 VM 的情況下登入:
- 工作階段自己的終端機會執行代理程式的登入指令,供應商的登入頁面則在你 Mac 的瀏覽器中開啟(「正在打開瀏覽器以登入…」)。
- 當代理程式用授權碼交換權杖時,代理伺服器會自行回應這次交換:真正的權杖會直接進入主機的存放區。Claude Code 與 Codex 會被告知憑證留在 Mac 上;Grok 與 Kimi 會收到替代權杖,由它們的 CLI 寫入各自的憑證檔案。
- 代理程式以替代值重新啟動(「已登入。正在重新啟動 …」)。
從聊天登入會取代機器原本讀取的登入:若機器有自己的登入就取代它,否則取代共用登入。若 5 分鐘內沒有任何登入送達代理伺服器,卡片會顯示「Bromure 未及時收到 供應商 的登入。您可以重試。」每台機器一次只能進行一個登入。
omp 沒有可以登入的帳號;它的卡片顯示「omp 需要一個模型提供者」,並改為提供 機器設定…。
警告: 不要為了修復已過期的登入而在 VM 內手動執行
/login(或代理程式的登入指令)。請使用卡片或 偏好設定 › 模型,讓權杖由主機擷取,而不是留在 VM 中。
Kimi 登入國際區域
Kimi Code 的 CLI 預設使用中國大陸區域,而該區域會拒絕其他地區的帳號。Bromure 會在註冊 VM 與每個工作階段中設定 CLI 的區域變數,讓 Kimi 登入國際區域(auth.kimi.ai,API 位於 api.kimi.ai)。在舊的 auth.kimi.com 區域擷取的 Kimi 登入仍會被辨識。
權杖保管:一個授權,一個更新者
權杖更新完全在主機端進行,而每個登入都由唯一的擁有者更新:
- 每個槽位一個授權。 共用登入與每台機器自己的登入是分開的槽位。每個槽位一次只會執行一次更新,而讀取該槽位的每台機器都使用其結果。客體永遠不會持有更新權杖。
- 更新時機。 主機會在到期前約 5 分鐘,向供應商的權杖端點更新(Claude 為
platform.claude.com、Codex 為auth.openai.com、Grok 為auth.x.ai、Kimi 為auth.kimi.ai)。剛註冊的登入會以已過期的狀態儲存,因此第一次使用就能證明更新路徑可行。 - 自動化的複製機器共用授權。 為自動化複製的機器會指向其基礎機器的登入,而不是拷貝一份。
- 你 Mac 上 CLI 自己的登入不會匯入。 與主機上的 CLI 共用授權,會導致每當其中一方更新時,另一方就被登出。
- 當沒有可用的權杖時,對於 Claude 請求,代理伺服器會自行回應代理程式,而不是轉送假金鑰:暫時性故障會以可重試的
529回傳,遭拒的登入則以401回傳,提示你從 Bromure 重新登入。此時彈出視窗會顯示 登入已過期。
服務憑證
AWS
AWS 獲得所有供應者中最深入的處理,因為 AWS 請求並非以 bearer 權杖驗證——它們是被簽署的(SigV4)。在工作區編輯器中開啟憑證 → AWS;一個分段控制項可在靜態金鑰與 SSO / Identity Center 之間選擇。
靜態金鑰與主機重簽署器
貼上你的存取金鑰 ID 與密鑰(外加一個選用的 STS 工作階段權杖與一個預設區域)。生命週期:
- 在 VM 中:
~/.aws/config指向一個 credential_process 輔助程式,它會——透過 vsock 連接埠 8445——提供真正的存取金鑰 ID,搭配一個 40 個字元的偽造密鑰,並省略工作階段權杖。每一個 AWS SDK、awsCLI、terraform 與 boto3 都會原生地採用它;不需要任何工具專屬的設定。 - 客體所做的事: 以偽造的密鑰簽署其請求,產生一個語法上有效但密碼學上註定失敗的 SigV4 簽章。
- 在傳輸途中: 主機的 AWS 重新簽署器會偵測送往任何分區之 AWS 的請求,無論使用 IPv4 或雙堆疊名稱(
*.amazonaws.com、*.api.aws、*.amazonaws.com.cn、*.api.amazonwebservices.com.cn、European Sovereign Cloud 與 ISO 分區的網域;包括 GovCloud、區域、FIPS 與 bucket 形式的 S3 主機),移除客體的簽章,在有工作階段權杖時注入真正的X-Amz-Security-Token,並在請求離開你的 Mac 之前以真正的秘密重新簽署。AWS 防護欄涵蓋相同的主機,下方 VM 建立之憑證的改寫也涵蓋這些主機,另加public.ecr.aws。每次成功的重新簽署都會發出一個帶有遮蔽存取金鑰的credential.aws_sign稽核事件,並在安全性時間軸中顯示為 憑證使用 列。
這在最強的意義上是失敗封閉的:真正的密鑰以任何形式都從不存在於 VM 中,而一個繞過代理伺服器的請求會被 AWS 以 InvalidSignatureException 拒絕。
有三種請求樣式不受支援,會向客體回傳一個明確的錯誤而非靜默失敗:分塊串流 S3 上傳(STREAMING-AWS4-HMAC-SHA256-PAYLOAD,以 501 回應)、SigV4A 非對稱簽署,以及預簽署的查詢字串 URL(它們將簽章嵌入重簽署器無法替換之處)。
VM 建立的憑證
有些呼叫會核發新的憑證:aws sts assume-role / get-session-token / get-federation-token、aws iam create-access-key、IAM Identity Center 的角色憑證、Cognito 的 GetCredentialsForIdentity、aws ecr get-login-password,以及 DigitalOcean 上的 doctl registry login、doctl kubernetes cluster kubeconfig save(及其憑證呼叫)與 doctl spaces keys create。代理伺服器會攔住這類呼叫的回應,在 VM 看到之前把其中的每一個機密都換成偽造值。臨時的 AWS 金鑰會保留其真正的存取金鑰 ID,搭配偽造的密鑰與工作階段權杖,讓重新簽署器能分辨客體是用哪一把金鑰簽署的。登錄庫或叢集的權杖會變成一個偽造值,只有在該登錄庫或叢集上才會被換回真正的值。
真正的值會加密儲存在工作區的設定中,因此 VM 存下的偽造值(在 ~/.aws、~/.docker/config.json 或 kubeconfig 中)在重新啟動後仍可繼續使用。核發的 AWS 金鑰會以它自己的密鑰與工作階段權杖重新簽署。一旦過期,以它簽署的請求會被拒絕,而不是改用工作區自己的金鑰重新簽署——那樣會以不同的身分執行這些請求。過期的憑證會在過期 30 天後被丟棄。
代理伺服器無法完整改寫的回應絕不會被轉交:客體會改為收到 502。設定由 VM 自行選擇之機密的呼叫,因為沒有任何偽造值能代替,在每一種防護欄模式下都會被拒絕:iam:CreateLoginProfile、UpdateLoginProfile、CreateServiceSpecificCredential 與 ResetServiceSpecificCredential。AWS 同意提示會標明它將簽署的呼叫(例如 sts:AssumeRole),而每一個核發的憑證都會發出一個 credential.minted 事件。
SSO / IAM Identity Center
如果你的組織使用 IAM Identity Center,請選擇 SSO / Identity Center 而非貼上長效金鑰:
- 按一下授予對 ~/.aws 的存取權並核准資料夾存取提示(一項安全範圍界定的授權;該資料夾是在主機上讀取,絕不掛載進 VM)。
- 從 SSO 設定檔挑選器中挑選你的設定檔。應用程式會探索
~/.aws/config中帶有sso_start_url、sso_account_id與sso_role_name的[profile …]區段,並解析[sso-session …]參照;帳戶 ID 與角色以唯讀方式顯示。 - 在工作階段啟動時,主機會從 SSO 權杖快取(
~/.aws/sso/cache)解析暫時性角色憑證。若快取的權杖已過期,你的瀏覽器會開啟以進行aws sso login——在主機上,從/usr/local/bin/aws執行。
解析出的暫時性金鑰饋入與靜態金鑰相同的重簽署器;VM 仍舊從不看見密鑰。憑證會在主機上於到期前約 5 分鐘自動刷新。
Bedrock
Amazon Bedrock 是供所有代理程式使用的模型供應商,而不是某一個代理程式的驗證模式。在 偏好設定 › 模型(或機器的 模型 窗格)的 Amazon Bedrock 彈出視窗中開啟 使用 Amazon Bedrock,然後為每個代理程式選擇 Bedrock 模型 ID。Claude Code 原生在 Bedrock 上執行;其他代理程式則透過 Bedrock 與 OpenAI 相容的 API 使用它。由於 Bedrock 端點是 *.amazonaws.com 主機,請求會透過同一條重新簽署路徑,以每台機器自己的 AWS 憑證(憑證 → AWS,靜態或 SSO)簽署——或者,若你在彈出視窗的 Bedrock API 金鑰(選填——否則由 AWS 憑證簽署) 欄位中貼上一把金鑰,就以該金鑰簽署,而 VM 只會看到假值 bedrock-brm-…。彈出視窗也接受 AWS 區域;留空即使用每台機器的 AWS 區域。請參閱模型與供應商。
Git HTTPS 權杖(GitHub、GitLab、Bitbucket、自架)
用於 git-over-HTTPS 的個人存取權杖位於 GitHub 權杖 / GitLab 權杖 / Bitbucket 權杖(統稱為 HTTPS 權杖)之下。每一項項目需要一個主機、一個使用者名稱與該權杖;自架的 GitLab 或 Gitea 執行個體只要設定主機欄位即可運作。生命週期:
- 在 VM 中: 一個偽造值會被寫入
~/.git-credentials與gh/glab設定;GH_TOKEN與GITLAB_TOKEN會被匯出,好讓這些 CLI 自動驗證。偽造值的形狀符合各廠商的驗證器(GitHub 為ghp_+ 36、GitLab 為glpat-+ 20,其他則為brm_…),因此gh與glab中的前綴與長度檢查得以通過。 - 在傳輸線路上: 對送往該項目 git 主機的請求,替換為真正的權杖。
- 核准: 每一項項目在防護欄窗格中都有自己的使用前先詢問列。
如果你只需要透過 SSH 進行 git push,你可能根本不需要 HTTPS 權杖——見下方 SSH 金鑰。
通用 API 金鑰(其他 API 金鑰 / 手動權杖規則)
對於任何應用程式並未自動處理的 API,請在其他 API 金鑰(即手動權杖規則,也以 MITM 權杖替換呈現)之下新增一項項目。按一下新增權杖並提供:
| 欄位 | 意義 |
|---|---|
| 名稱 | 該項目的標籤。 |
| 值 | 真正的密鑰(以加密形式存放在主機上)。 |
| 環境變數名稱 | 偽造值在 VM 內部匯出時所用的變數。從你的程式碼中參照它。 |
| 主機篩選(選用) | 該替換的主機範圍。 |
有兩種邊界情況是刻意設計的:
- 空的環境變數名稱: 不匯出任何東西;你從工作階段的歡迎橫幅複製偽造值,並將它放到你的工具所需之處。
- 空白的主機篩選: 真值會在任何主機上注入,不加詢問。這是一個明確的永遠開啟選擇——對於有許多區域性主機名稱的 API 很有用——但這代表該憑證的範圍不再保護它。若要為一個未界定範圍的密鑰設閘門,請在防護欄窗格中為它開啟使用前先詢問(或者終究還是給它一個主機篩選)。
Anthropic、OpenAI、GitHub、GitLab、DigitalOcean 與 Kubernetes 在此處永遠不需要手動項目。
1Password 密鑰參照(op://)
除了貼上真正的密鑰之外,一個其他 API 金鑰的值也可以是一個 1Password 密鑰參照——op://vault/item/field,或 op inject 與 .env.op 檔所使用的大括號形式 {{ op://vault/item/field }}。磁碟上永遠只儲存那個參照;密鑰本身絕不會寫入主機或 VM 上的任何地方。編輯器會辨識該參照、以明文顯示它(它並非密鑰),並註明它是透過 1Password 解析。
在每次工作區啟動時,Bromure 會在主機端以 1Password CLI(op read)解析該參照,從參照字串產生一個偽造值(如此即使密鑰輪替,偽造值仍維持穩定),並只將該偽造值匯出至 VM。接著 MITM 代理伺服器會在傳輸線路上將偽造值替換為解析出的值,就如同它對一個貼上的密鑰所做的一樣——而且它會每 2 分鐘重新解析一次,因此在 1Password 中輪替該項目會在幾分鐘內生效,無需重新開機。
這需要安裝並登入 op CLI——透過 1Password 應用程式的生物辨識解鎖,或在終端機中執行 op signin。如果找不到 op,編輯器會顯示一個取得 1Password CLI 連結,且工作區會在啟動時呈現安裝說明;如果解析失敗(未登入,或項目不存在),Bromure 會呈現該錯誤,好讓你修正並重新啟動工作區。
匯入 .env 或 .env.op 檔案(憑證窗格中的 匯入 env 檔案…)時,會自動辨識 op:// 值——無論是 ANTHROPIC_API_KEY 這類已辨識的名稱,還是 STRIPE_KEY 這類任意名稱——並把每一個儲存為存放該參照的手動權杖。
DigitalOcean
在憑證 → DigitalOcean 之下貼上一個個人存取權杖(在瀏覽器中開啟 DigitalOcean 權杖頁面連結會帶你前往權杖產生頁)。偽造值(dop_v1_ + 十六進位,64 個字元)會匯出為 DIGITALOCEAN_ACCESS_TOKEN 並寫入 ~/.config/doctl/config.yaml,因此不需要 doctl auth init。此替換涵蓋送往 digitalocean.com 的請求,外加第二項項目,用於 docker login / doctl registry login 對 registry.digitalocean.com 所使用的 base64 Basic-auth 區塊,如此登錄的推送與提取也能解析。
Linear
在 憑證 → Linear 下貼上個人 API 金鑰(連結:在瀏覽器中開啟 Linear API 設定;金鑰可在 linear.app → Settings → API 取得)。假值(lin_api_ + 40)會以 LINEAR_API_KEY 匯出,Linear SDK、MCP 伺服器與 CLI 工具都會自動讀取;替換嚴格限定於 linear.app(GraphQL 位於 api.linear.app,MCP 位於 mcp.linear.app)。工作區上的 Linear 金鑰也是 Linear issue 自動化觸發器的先決條件——請參閱自動化。
Twilio
新增一個 Twilio API key 憑證,把 SID 填入 Account SID (AC…) or API Key SID (SK…),把機密填入 Auth Token / API Key secret(兩者皆來自 console.twilio.com)。Twilio 使用 HTTP Basic 驗證,其中 SID 是一種身分——會出現在請求網址中——只有權杖是機密。生命週期:
- 在 VM 中:
TWILIO_ACCOUNT_SID存放真正的 SID,TWILIO_AUTH_TOKEN則存放假值brm-twilio-…,讓 Twilio SDK 與 CLI 不必設定就能讀取。 - 在傳輸途中: 在送往
twilio.com的請求中,代理伺服器會把單純的假權杖,以及預先以 base64 編碼的SID:權杖Basic 驗證區塊,都換成真值。 - 核准: 透過防護欄窗格中的 使用前詢問。
匯入 env 檔案… 能辨識 TWILIO_ACCOUNT_SID/TWILIO_API_KEY_SID 與 TWILIO_AUTH_TOKEN/TWILIO_API_SECRET,並把它們組合成一個 Twilio 憑證。
MCP 伺服器 bearer 權杖
在 MCP 窗格中設定的 HTTP 傳輸 MCP 伺服器會獲得相同的處理:真正的 bearer 權杖留在主機上,一個 brm-mcp_… 偽造值被注入代理程式所讀取的 MCP 設定中,代理伺服器則在傳輸線路上替換它,範圍界定為該伺服器的主機。只有已啟用、且 bearer 權杖非空的 HTTP 傳輸伺服器才會獲得一筆替換項目。
還有一項額外的貼心處理:對於帶有 brm-mcp_ 項目的主機,代理伺服器會以 404 回應 OAuth/OIDC 探索路徑(.well-known authorization-server、protected-resource 與 OpenID configuration 端點)。Claude Code 於是將該伺服器視為已預先驗證,而非嘗試其自己的 OAuth 流程——反正該流程在 VM 內部也永遠無法完成。
容器登錄(Docker Hub、GHCR 及其同類)
憑證 → 容器登錄管理用於 docker pull/push 的 HTTP Basic 驗證。已有 Docker Hub(docker.io)、GitHub Container Registry(ghcr.io)與 GitLab Container Registry(registry.gitlab.com)的預設值;任何其他登錄都可以依主機新增。生命週期:
- 在 VM 中:
~/.docker/config.json包含一個偽造的驗證區塊——你的使用者名稱搭配一個衍生的brm-docker-…密碼的 base64——如此 Docker 便相信它已登入。 - 在傳輸線路上: 代理伺服器在相符的登錄主機上替換真正的 base64 區塊。distribution-spec 的權杖交換也會處理:會為已知的驗證領域新增替換項目(Docker Hub 對
auth.docker.io驗證,DigitalOcean 的登錄對api.digitalocean.com驗證)。 - 匯入: 按一下匯入 config.json…,從主機上一個現有的
~/.docker/config.json拉取項目。委派給credsStore/credHelpers的項目會被略過——它們的密碼存放在作業系統的鑰匙圈中,而非檔案裡——匯入摘要會回報略過了多少個以及原因。 - 核准: 依登錄,透過防護欄窗格中的使用前先詢問。移除此登錄會刪除一項項目。
Kubernetes 環境定義
憑證 → Kubernetes 將 kubeconfig 環境定義轉為由代理伺服器中介的叢集存取。按一下匯入 kubeconfig將一個現有的 kubeconfig 剖析為每個環境定義一列(current-context 排在最前,驗證類型自動偵測),或按一下新增環境定義手動輸入伺服器 URL、憑證、命名空間與叢集 CA。無論何種情況,VM 都會收到一份合成的 ~/.kube/config:客體中的 kubectl 是與代理伺服器(透過 Bromure CA 信任)對話,絕不直接與 API 伺服器對話。
依驗證類型:
- Bearer 權杖環境定義在 VM 中獲得一個
brm-k8s-…佔位值,在傳輸線路上替換為真正的權杖。 - 用戶端憑證環境定義在 VM 中獲得一張用完即棄的自簽憑證與金鑰;真正的憑證與金鑰在主機上註冊為一個
SecIdentity,並用於上游 mTLS。 - Exec 外掛程式環境定義根本從不在 VM 中執行該外掛程式。exec 外掛程式輪詢器會在主機上於每個刷新間隔(預設 600 秒,下限 60)執行該指令,剖析
ExecCredentialJSON,並將新鮮的權杖饋入替換對應表。刷新會保留該項目的同意狀態。
如果 kubeconfig 提供了叢集自己的 CA,它會被轉送,好讓代理伺服器能驗證上游 API 伺服器。匯入的 kubeconfig 中的檔案路徑欄位(CA、憑證、金鑰)會在匯入時急切讀取——之後對那些磁碟上檔案的變更不會被採納。每個環境定義在防護欄窗格中都有自己的使用前先詢問列,在那裡一項寫入原則還可以在任何位元組被轉送之前,於主機端剝除具破壞性的動詞(kubectl delete、AWS Delete*/Terminate*、docker push、git push)——這是與憑證替換分開的一層。
HTTP 資料庫(MongoDB、ClickHouse、Elasticsearch)
憑證 → 資料庫(MongoDB / ClickHouse / Elasticsearch 區段)涵蓋以 HTTPS 溝通的資料庫端點——Mongo Data API、ClickHouse 的 HTTP 介面、Elastic。每一個端點需要一個引擎、主機、密鑰、使用者名稱、驗證類型,以及一個或多個環境變數名稱(以逗號分隔),brm-db-… 偽造值會在這些名稱下匯出;從你的程式碼或連線字串中參照那些變數。
資料庫憑證是唯一一個替換會同時掃描請求本文以及標頭與查詢參數的家族,因為連線密鑰經常夾帶在 JSON 或 SQL 酬載內部。代理伺服器會在本文替換後修補 Content-Length;其他流量中無關的 multipart 或二進位本文絕不會被觸碰(所有其他替換都僅限標頭)。Basic-auth 端點也會替換其 base64 的使用者與密鑰區塊。各端點的使用前先詢問與寫入原則是在防護欄窗格中設定。
SSH 金鑰
SSH 是在完全不用任何權杖的情況下處理的:VM 的 SSH_AUTH_SOCK 由一個透過 vsock(連接埠 8444)的 ssh-agent 橋接器支援。客體可以列出身分並請求簽章,但私鑰的位元組只存在於主機上,並且在物理上無法從 VM 內部讀取或擷取。存在兩個金鑰來源,兩者都在憑證 → SSH 金鑰之下:
- 各工作區的預設金鑰。 一把共用的預設 ed25519 金鑰對會在應用程式啟動時產生(存放於 Application Support 中的
default-ssh/之下),並複製到每個新工作區的代理程式目錄。此窗格會顯示該工作區的公鑰,好讓你將它貼入你的 git 主機(GitHub 為 github.com/settings/keys)。你也可以從 CLI 以bromure-cli workspaces ssh-keygen <workspace-id|name>產生一把新鮮的金鑰,它會印出新的公鑰。 - 匯入的金鑰。 在匯入的 SSH 金鑰之下按一下匯入… / 匯入檔案…,並將應用程式指向一個現有的私鑰檔——支援 RSA、ed25519 與 ECDSA,包括加密的金鑰。加密的金鑰會在匯入時提示輸入其複雜密碼一次;該複雜密碼儲存在 macOS 鑰匙圈中(服務
io.bromure.agentic-coding.ssh-key-passphrases),並在啟動時透過SSH_ASKPASS提供,絕不記錄。匯入金鑰的簽署流程會通過應用程式為自己衍生的一個私有 ssh-agent 行程(在暫存目錄下某個 socket 上的ssh-agent -D)——與你系統上的其他任何東西分開。 - 主機代理程式的金鑰。 私密金鑰無法離開其裝置的金鑰——透過 gpg-agent、Secretive、1Password 使用的 YubiKey 或其他安全金鑰——則改用從主機代理程式…加入。選擇代理程式的 socket(留空 = 應用程式自己的
SSH_AUTH_SOCK;從 Finder 開啟的應用程式,這是 macOS 的代理程式,而不是你的 shell 匯出的那個;gpg-agent 請用~/.gnupg/S.gpg-agent.ssh),按一下載入,再勾選工作區可以使用的金鑰。不會複製任何東西:VM 只看得到勾選的金鑰——而且只在代理程式持有它們時,所以拔掉的金鑰不會被提供——它們的簽章請求會轉送給該代理程式,因此觸碰或 PIN 提示會照常出現在你的 Mac 上(請求最多等候兩分鐘)。代理程式的其他金鑰對 VM 保持不可見,要求以其中一把簽章的請求會被拒絕。
對於每一把匯入的金鑰,在防護欄窗格中開啟使用前先詢問,會讓每一個 VM 內的簽章請求都提示徵求同意。每一個簽章——無論是預設或匯入的金鑰——都會發出一個 credential.ssh_sign 稽核事件,攜帶該金鑰的 SHA256 指紋以及它是受管理、匯入還是主機代理程式的金鑰。
附註: 你的 macOS 登入 ssh-agent(launchd 那個)——或任何其他主機代理程式——刻意絕不整個暴露給 VM。只有各工作區的金鑰、你明確匯入的金鑰,以及你逐一挑選的主機代理程式金鑰,才能從一個工作階段觸及。
每次使用核准與授權期限
本章中的任何憑證都可以被標示為使用前先詢問——這是防護欄窗格中一個各憑證專屬的核取方塊(在控制項本身上標示為需要核准才能使用),預設關閉,在 UI 中描述為:「在某個工作階段中首次使用此憑證時彈出一個確認對話方塊。」
當一個設有閘門的憑證在某個工作階段中首次被使用時,代理伺服器會保留該請求並顯示一個標題為**允許「工作區名稱」使用憑證?**的同意對話方塊(其中填入你工作區的名稱與該憑證的標籤),提供四個按鈕:
| 按鈕 | 授權 |
|---|---|
| 允許 5 分鐘 | 有時限;該憑證會在 5 分鐘內順暢流通而不再提示。 |
| 允許 1 小時 | 有時限,1 小時。 |
| 在本次工作階段中持續允許 | 直到機器的 VM 關機為止。 |
| 不允許 | 該請求被拒絕;此拒絕會被記住 5 分鐘,好讓一場代理程式的重試風暴不會產生一場對話方塊風暴。 |
值得了解的行為:
- 合併。 需要同一個憑證的並行請求會合併到一個對話方塊上——一個話多的代理程式發出十二個平行 API 呼叫只會產生一個提示,而這十二個全都會遵循你的決定。
- 拒絕優先。 一個生效中的拒絕會在任何較舊的允許被查閱之前就短路。
- 設計上即為短暫。 授權與拒絕只保存在記憶體中,並會在 VM 關機時撤銷。「工作階段的剩餘時間」絕不會延續到 VM 重新啟動之後,也不會有任何東西在應用程式的兩次執行之間保留。
- 無頭工作階段。 在 SSH 或無頭工作階段中,提示會出現在機器的 tmux 中,而不是圖形化警示——請參閱遠端存取。
對於 AWS,此閘門適用於每一次主機端的簽署呼叫;對於 SSH 金鑰,適用於簽章請求;對於其他一切,適用於該工作階段的第一次傳輸線路替換。
提示: 此同意閘門是依憑證而非依主機。如果你想讓一個未界定範圍的手動權杖維持在控制之下,核准正是為它設計的機制。
憑證核准視窗
視窗 → 憑證核准…會開啟一個即時檢視,顯示目前應用程式執行期間所做的每一個同意決定:有時限的允許(5 分鐘 / 1 小時 / 工作階段剩餘時間)與被記住的拒絕。每一列顯示工作區名稱與剩餘時間,並提供撤銷;全部撤銷(⌘⌫)可一次清除所有內容。此清單每 2 秒自動重新整理,並隨著授權到期而自然縮減。
由於決定只存在於記憶體中,因此在授權到期後、VM 關機後(工作階段範圍的授權),以及應用程式結束後,視窗都會是空的。它是針對當下的控制面板,而不是稽核記錄——若要查看歷史,請使用安全性時間軸與追蹤。
入侵偵測器
這些偽造值身兼二職:除了代替密鑰之外,它們還是絆索。一個偽造權杖只有一個正當的目的地家族——它所產生的主機範圍。沒有任何誠實的理由讓 sk-ant-api03-brm-… 出現在一個送往 pastebin.example 的請求中。因此代理伺服器會掃描每一個外送請求——標頭與本文,透過一個 Aho-Corasick 自動機,其成本低廉到足以在所有東西上執行——尋找任何前往其範圍之外的偽造值。
當它找到一個時,便將該請求視為企圖進行的憑證外洩:
- 該請求被以 HTTP 451 封鎖。連一個位元組都不會被轉送到目的地。
- VM 會立即暫停。若機器原本在背景執行,會先被帶到畫面上,其凍結的畫面會染成紅色。
- 一個嚴重警示會出現,標題為 此環境可能已遭入侵:「Bromure 偵測到一次從「機器」向未獲授權的主機外洩工作階段憑證的對外嘗試。虛擬機器已暫停。」在 偵測到的洩漏: 之下,每次洩漏列出一行——權杖預覽(例如
sk-a…f9q3)、憑證名稱、它原本核發給的主機,以及它被送往的主機。 - 這次偵測會在安全性時間軸中記錄為紅色的 憑證中介 列,在已註冊的安裝上也會記錄為
credential.exfiltration事件。
警示提供四個按鈕:
| 按鈕 | 效果 |
|---|---|
| 關機(預設) | 停止 VM,並把機器標記為已遭入侵。 |
| 封鎖 | 只攔下這一個請求(它已收到 451),並恢復 VM。不會記住任何東西:若代理程式再試一次,偵測器會再次觸發,警示也會再次開啟。 |
| 允許 | 僅在本次工作階段的剩餘時間內信任所觀察到的主機,並恢復 VM。此後憑證會被替換並送往該主機(及其子網域),送往它的請求也不再被標記。這個決定會記錄為綠色的 憑證中介 列「allowed by user for this session」,在已註冊的安裝上也會記錄為 credential.exfiltration_allowed。允許清單會在 VM 關機時清除。 |
| 儲存以供調查 | 要求選擇一個檔案夾,匯出 disk.img(VM 系統磁碟的副本)、home.tar.gz(機器的家目錄),以及每個共用檔案夾的 shares/<名稱>.tar.gz,然後關閉 VM 並把機器標記為已遭入侵。VM 的 RAM 狀態會被捨棄。 |
只有 關機 會回應 Return 鍵;封鎖、允許 與 儲存以供調查 都沒有鍵盤對應,因此要恢復一台可能具敵意的 VM——更別說把憑證送給它——一律需要明確點按。一次只會顯示一個警示;警示開啟期間重複的偵測會被捨棄(每一次仍會被封鎖)。
提示: 允許 是為了正當的跨主機設定而存在——例如某個工具刻意把 OpenAI 格式的金鑰送到另一個供應商與 OpenAI 相容的端點。如果你不認得該目的地,就不要允許。
若機器正由遠端用戶端鏡像,問題會以待處理提示的形式出現在用戶端上,並提供 關機、封鎖 與 允許(儲存以供調查需要本機的檔案夾選擇器,因此只在 Mac 本身上提供)。只有受影響的 VM 會保持暫停;主機會繼續服務其他所有機器。無人回應的提示會在 3 分鐘後關閉 VM。
被標記為已遭入侵的機器,在你處理之前會拒絕啟動。啟動它時會顯示 「To continue, the VM disk image and the persistent home folder must be wiped. Your tokens, ssh keys, and workspace settings are preserved.」,並提供 清除並啟動 與 取消(Return 鍵不會確認清除)。請留意隨附的警告:共用檔案夾不會被清除,因此如果入侵是透過共用檔案夾中的套件或檔案而來,它可能仍在那裡——恢復工作前請先檢查這些檔案夾。
對一則入侵警示的建議回應:開啟追蹤檢視器(⇧⌘I)或執行 bromure-cli trace leaks 以查看違規的主機與請求,判斷是某個專案相依項還是一條提示注入的指示要負責(見提示注入與供應鏈),然後清除並重新啟動。
範圍細節:
- 未界定範圍的偽造值可豁免。 一個帶有空白主機篩選的手動權杖依設計就是「任何主機」,無法觸發偵測器;假的訂閱佔位值同樣也被排除在外。
- 第一方的手足可容忍。 比對會鏡像替換的範圍原則,只放寬一項:與該憑證供應者位於同一個註冊網域下的主機(例如
anthropic.com下的 Claude 或 Codex 基礎設施)使用家族比對,因此一個正當的api.anthropic.com權杖出現在mcp-tools.anthropic.com上並不算是誤報。其餘一切皆嚴格處理。 - 看起來像真值的洩漏也會被標示。 獨立於偽造值絆索之外,代理伺服器會標示外送流量中未替換、看起來像真值的密鑰——帶有已知前綴(
sk-ant-、ghp_、AKIA、…)的Bearer或x-api-key值,或 20 個字元以上的不透明權杖。這些會在追蹤檢視器與bromure-cli trace leaks中顯示為洩漏警告;它們通常意味著有一個真正的密鑰被手動貼入 VM,而傳輸邊界的存在正是為了讓這件事變得不必要。
偵測器本身永遠開啟。你可以按機器關閉的是中斷——請參閱下一節。
應急做法
有些主機與用戶端在完整攔截下無法運作:主機不信任的私人 CA 伺服器、會釘選其伺服器憑證的用戶端,或是一再觸發入侵警示的正當設定。防護欄窗格底部的三個機器專屬設定,能在這些情況下放寬邊界而不關閉它。三者都會即時套用,無需重新啟動。
| 設定 | 預設 | 作用 |
|---|---|---|
| 允許逐一請求的不安全繞過(X-bromure-insecure) | 開啟 | 當送往自我簽署或私人 CA 主機的請求未通過憑證驗證時,代理程式可以帶上標頭 X-bromure-insecure: yes 重試,以略過該上游的憑證驗證。攔截、追蹤與防洩漏保護仍然開啟,而 Bromure 不會在這類請求中注入任何真正的憑證——送出去的只有客體的假值。每次使用都會在安全性時間軸中記錄為 上游 TLS 列:「allowed — certificate validation skipped (X-bromure-insecure); no credentials injected」。預設開啟,因為它只有在客體送出該標頭時才會作用;關閉它即可完全禁止該標頭。 |
| 停用透明攔截 | 關閉 | 停止把 VM 的 HTTP/HTTPS 強制導向 Bromure 的網路層轉向。原始通訊端與釘選憑證的用戶端會因此直接連到真正的網路與真正的上游憑證。代理伺服器本身仍保留:HTTP(S)_PROXY 依然設定,因此會遵循代理伺服器設定的工具(apt、git、pip、curl、node…)以及代理程式自己的 API 呼叫仍會經過 Bromure,並保有憑證替換、追蹤與防護欄。忽略代理伺服器設定的流量則不再受連外規則涵蓋。 |
| 憑證外洩時不發出警示 | 關閉 | 抑制入侵警示與 VM 暫停。外洩中的請求仍會以 451 封鎖,也仍會記錄在安全性時間軸中(「blocked — exfiltration attempt (alerts off, VM not paused)」);消失的只有中斷。 |
警告: 這些設定都是以部分防護換取相容性。請優先選擇範圍最窄的:針對單一不受信任憑證使用逐一請求的標頭,針對單一受信任目的地使用入侵警示中的 允許,而整台機器的開關只用於別無他法的機器。
密鑰在主機上存放於何處
一切敏感的東西都以 AES-GCM 在一把各安裝專屬的 256 位元主金鑰下靜態加密——即密鑰保險庫。主金鑰存放於 macOS 的 Data Protection Keychain,範圍界定至應用程式的簽署身分,其可存取性為 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,且 iCloud 同步已停用。它從不提示、從不同步,也從不離開 Mac。如果鑰匙圈無法觸及(一個未簽署或未佈建的組建),應用程式會退回到一個模式為 0600、存放在密文旁邊的金鑰檔——較弱,因為金鑰與密文於是共享一個磁碟,但它仍讓靜態加密持續運作;一個完全佈建的正式版本會使用鑰匙圈。
實務後果:
- 備份與副本都是密文。 一份 Time Machine 備份或一個複製的
Application Support資料夾只包含加密的區塊;沒有這台 Mac 的鑰匙圈項目便無法解密它們(除非當時使用的是檔案退回金鑰,且一併被複製)。 - 清除鑰匙圈項目會輪替金鑰。 現有的加密區塊會變得無法讀取,而你需要重新輸入你的憑證。
profile.json中的非敏感中繼資料不受影響。 - 沒有任何東西同步到任何地方。 應用程式本身不會上傳、同步或備份任何憑證、權杖存放區或金鑰材料。
磁碟上的位置,除非另有說明,全都在 ~/Library/Application Support/BromureAC/ 之下:
| 位置 | 內容 |
|---|---|
ca/cert.pem、ca/key.pem | Bromure Agentic Coding Root CA(金鑰模式 0600)。刪除此目錄即可輪替。 |
fake-salt.bin | 偽造值衍生背後的各安裝專屬 32 位元組 HKDF 鹽值(0600)。刪除它會輪替這台 Mac 上的每一個偽造值。 |
claude-subscription.enc、codex-subscription.enc、grok-subscription.enc、kimi-subscription.enc | 以 AES-GCM 加密的訂閱存放區:共用登入加上每台機器自己的登入,0600。 |
models.enc | 偏好設定 › 模型 的全域模型設定,包括供應商的 API 金鑰,以保險庫金鑰加密。 |
pii/<workspace-id>.key | 個人資料保護替代值背後、每台機器專屬的金鑰(0600)。 |
secrets-master.key | 0600 的退回主金鑰——僅在 Data Protection Keychain 無法觸及時存在。 |
default-ssh/id_ed25519.raw、default-ssh/id_ed25519.pub | 共用的預設 SSH 金鑰對,會拷貝到新機器中。 |
profiles/<id>/ssh/ | 為每台機器核發的 SSH 金鑰(代理程式目錄)。 |
鑰匙圈:io.bromure.agentic-coding.master-key | AES-256 保險庫主金鑰(帳戶 v1),Data Protection Keychain。 |
鑰匙圈:io.bromure.agentic-coding.ssh-key-passphrases | 匯入的 SSH 金鑰複雜密碼,每個設定檔/金鑰檔一項。 |
用於匯入的主機端讀取——~/.aws/config、~/.aws/sso/cache/*.json、~/.docker/config.json、kubeconfig 檔——只在主機上發生;那些檔案沒有任何一個會被掛載進 VM。加密的追蹤本文(見追蹤)使用相同的保險庫金鑰。
自行驗證此邊界
傳輸邊界的設計是可查核的,而非要人盲信。從任何工作階段內部的一個 shell:
1. 環境持有偽造值。
echo "$ANTHROPIC_API_KEY"
# sk-ant-api03-brm-… ← a fake, not your key
env | grep -E 'TOKEN|KEY'
# every value is brm_/ghp_/glpat_/dop_v1_/lin_api_-shaped placeholder
2. 設定檔持有偽造值。
cat ~/.git-credentials # fake tokens per git host
cat ~/.docker/config.json # fake base64 auth blobs
grep -A2 credential_process ~/.aws/config # helper, not a secret key
3. 然而,一切都能運作。
aws sts get-caller-identity # succeeds — the host resigned the request
gh api user # succeeds — the fake was swapped on the wire
4. VM 內部的 TLS 在代理伺服器處終止。
openssl s_client -connect api.anthropic.com:443 -brief 2>&1 | head
# issuer: the Bromure Agentic Coding Root CA — not a public CA
5. SSH 金鑰不存在,但簽署可運作。
ssh-add -L # lists public keys served by the vsock agent
ls ~/.ssh/id_* # no private key files to find
6. 在主機上觀察替換的發生。 開啟安全性時間軸並以 憑證中介 篩選:每次替換都會顯示為像 sk-a…f9q3 → api.anthropic.com — swapped in … 這樣的一列。若已為該機器開啟追蹤,你也可以執行:
bromure-cli trace summary # per-request swap reports and leak warnings
bromure-cli trace leaks # only the suspicious ones
或開啟追蹤檢視器(⇧⌘I),其中被替換的請求會被註記為從未送至 VM——由代理伺服器替換。
如果你曾在一個 VM 內部發現一個真正的憑證,它以兩種方式之一到達那裡:你(或在你指示下的代理程式)手動貼入了它,或它是透過一個共用資料夾抵達的。替換機制從不將真值寫入客體——而入侵偵測器將傳輸線路上看起來像真值的密鑰視為洩漏,正是因為它們本不應存在於那裡。
快速參考
客體與主機邊界上的 vsock 連接埠:
| 連接埠 | 用途 |
|---|---|
| 8443 | HTTPS MITM 代理伺服器——客體的整個出口。 |
| 8444 | SSH_AUTH_SOCK 背後的 ssh-agent 橋接器。 |
| 8445 | AWS credential_process 輔助程式。 |
| 8446 | 註冊 VM 使用的 Claude 權杖通道——它與本機推論橋接共用此連接埠(兩者在不同的流程中建立;請參閱模型與供應商)。 |
| 8447 | 註冊 VM 使用的 Codex 權杖通道(存取、更新與 ID 權杖)。 |
兩條權杖通道都是單向的:主機只能把假值寫入 VM,而 VM 只能把真值送出給主機。不存在任何能讓 VM 把真正權杖要回去的請求。
相關的 CLI 指令(完整參考請見 CLI、API 與 MCP):
| 指令 | 用途 |
|---|---|
bromure-cli workspaces create --auth token|subscription|bedrock|local | 以其主要代理程式的驗證模式建立工作區。 |
bromure-cli vm run --auth token|subscription|bedrock|local | 啟動 VM,並為臨時建立的工作區選擇驗證模式。 |
bromure-cli workspaces ssh-keygen <workspace> | 在主機端產生一把新鮮的工作區 SSH 金鑰並印出公鑰。 |
bromure-cli trace summary [workspace] | 摘要已追蹤的流量,包括替換與洩漏警告。 |
bromure-cli trace leaks [workspace] | 顯示帶有潛在憑證洩漏的已追蹤請求。 |