概念與架構

Bromure Agentic Coding 在你自己 Mac 上的硬體虛擬化 Linux 機器內執行 AI 編碼代理程式,並在代理程式無法繞過的單一位置強制執行每一項安全控制。本章定義了本手冊其餘部分所依賴的詞彙——主機與客體、工作區與工作階段、傳輸邊界、持久性與暫時性儲存——並說明各部分如何組合在一起。如果在快速入門之外你只讀一章,就讀這一章。

主機與客體

Bromure Agentic Coding 中的一切都位於一條硬性界線的其中一側:

  • 主機是你的 Mac——macOS 14 或更新版本、搭載 Apple Silicon——以及在其上執行的 Bromure Agentic Coding 程序。主機擁有一切敏感內容:你的真實憑證(以 macOS Keychain 中的主金鑰加密)、代表代理程式與網際網路通訊的 MITM 代理伺服器、Bromure 根 CA 的私鑰、追蹤記錄儲存,以及應用程式的視窗、終端機與儀表板。你輸入的終端機是在主機上算繪的,而不是在 VM 內。
  • 客體是代理程式實際執行所在的 Linux 虛擬機——Claude Code、Codex CLI、Grok CLI 或純粹的 shell 工具,連同它們安裝與碰觸的一切:複製的儲存庫、套件快取、Docker 容器、虛擬環境。客體在設計上被視為不可信任。它不持有任何真實密鑰,只有刻意設為無效的假憑證,而其對外 HTTPS 全部透過主機的代理伺服器導流。

兩側透過兩條狹窄通道通訊:用於控制、終端機與代理路徑的 vsock(virtio 通訊端,一種完全不需要網路的主機對客體傳輸),以及用於一般 IP 流量的私有虛擬網路(vmnet NAT)。兩者都會在下方詳細說明。

這種分割使產品的安全宣稱變得具體:遭到提示注入或行為異常的代理程式可以在客體內部為所欲為,但它無法讀取真實的 API 金鑰、無法以真實的 AWS 密鑰簽署,也無法擷取 SSH 私鑰——這些在它那一側的界線上根本不存在。

架構一覽

Bromure Agentic Coding 架構:macOS 主機程序(工作階段視窗、密鑰保險庫,以及在傳輸線上將假憑證換成真實憑證的各工作區專屬 MITM 代理伺服器)透過 vsock 橋接連接到持久性的 Ubuntu 工作區 VM,以及一個共用私有 vmnet NAT 交換器的暫時性 Chromium 瀏覽器附屬 VM。

由下往上閱讀此圖:代理程式在工作區 VM 中工作;其 HTTPS 透過 vsock 離開,前往主機代理伺服器,那是假憑證變成真實憑證的唯一位置;工作階段視窗透過各自獨立的 vsock 橋接連接到 VM 的終端機;而一個選用的可拋棄式瀏覽器 VM 共用同一個私有網路,因此它可以載入代理程式的開發伺服器。

工作區、工作階段與 VM

在本手冊中,有三個詞承載著精確而各異的意義:

  • 工作區是一份已儲存的設定加上其持久性儲存。它定義了執行哪個代理程式(以及它如何驗證)、憑證、共用資料夾、環境、MCP 伺服器、防護欄、外觀,以及 VM 規格——凡是你在編輯工作區視窗中編輯的一切——並且它擁有一個位於 ~/Library/Application Support/BromureAC/profiles/<uuid>/ 下的目錄,保存其系統磁碟、家目錄映像、SSH 金鑰、檢查點與已儲存狀態。無論有沒有任何東西正在執行,工作區都存在。在內部(在諸如 profile.json 的檔案名稱與 CLI 旗標中)工作區被稱為 profile;這兩個詞可互換使用。典型的做法是每個專案或每個憑證界線各設一個工作區。請參閱工作區
  • VM(虛擬機)是從工作區儲存啟動的執行中 Linux 執行個體。每個工作區恰好對應一個 VM——一個具有自己磁碟、確定性 MAC 位址、IP 位址與各工作區專屬 MITM 代理伺服器監聽器的 Ubuntu 客體。兩個工作區絕不共用一個 VM,一個工作區也絕不會有兩個 VM。
  • 工作階段是工作區 VM 的一次連續執行:它從你啟動(或恢復)工作區時開始,並在 VM 關機或暫停時結束。工作階段視窗可以在不結束工作階段的情況下與其分離——在背景執行這個關閉動作會讓 VM 以無介面方式繼續執行,你稍後可以從側邊欄重新連接。有些狀態刻意以工作階段為範圍:憑證核准授予與拒絕僅存在於記憶體中,並在工作階段拆除時撤銷,而各次啟動的中繼資料共用區則在每次開機時重建。請參閱工作階段

一個實用的簡記法:工作區是名詞(它在磁碟上持久存在),VM 是機器(它在開機或暫停期間存在),而工作階段是執行(它有開始與結束)。

工作區 VM

每個工作區 VM 都是在 Apple 的 Virtualization.framework 下執行的 Ubuntu 24.04 客體——與 macOS 本身所提供的相同 Hypervisor 技術,需要 Apple Silicon 且僅支援 ARM64 客體。VM 以固定的 4 vCPUs 以及工作區中所設定的 RAM 量(預設依你的 Mac 調整規格:4、6 或 8 GB)從兩個虛擬磁碟開機:

  • disk.img——系統磁碟。在工作區首次啟動時,它會建立為共用且已簽署的 Ubuntu 基底映像檔的 APFS 寫入時複製(copy-on-write)複製體(請參閱安裝):該複製體會立即出現,且在客體寫入之前不會消耗任何新的磁碟空間。之後的啟動會重複使用同一個複製體,因此你 apt install 的套件、你拉取的 Docker 映像,以及任何其他系統層級的變更都會跨工作階段保存。
  • home.img——一個私有的稀疏 ext4 映像,保存 /home/ubuntu,作為第二個 virtio-blk 裝置掛載。它預設的表觀大小為 64 GiB,但採惰性配置,並會在客體中刪除檔案時於主機上收縮。家目錄即使在重設磁碟後也會存續,這就是為什麼你的儲存庫、dotfiles 與 shell 歷史會比系統磁碟重設更長久。(較舊的工作區可能仍使用舊式的共用資料夾家目錄;應用程式提供一次性升級——請參閱工作區。)

客體還會掛載小型的各次啟動 virtiofs 共用區:一個唯讀的中繼共用區,攜帶該次開機的設定(假權杖環境檔、代理設定、Bromure CA 憑證、客體代理、MCP 設定),以及一個可寫入的寄件匣(outbox),供客體用來將事件發佈回主機(其 IP 位址、tmux 分頁清單、代理狀態)。兩者都在每次開機時重建,且不攜帶任何持久性狀態。此外最多可將 8 個主機專案資料夾共用進客體,以符號連結連入家目錄。

設計上即為持久——與 Bromure(Web)的對比

Bromure Agentic Coding 與其姊妹應用程式 Bromure——網頁瀏覽器變體——出自同一份程式碼庫,而兩者刻意做出相反的生命週期選擇:

Bromure(Web)Bromure Agentic Coding
客體映像Alpine + ChromiumUbuntu 24.04
VM 存續期每次瀏覽工作階段一個用完即丟的 VM,視窗關閉時銷毀每個工作區一個持久性 VM,跨工作階段重複使用
關閉時的資料一切都銷毀系統磁碟與家目錄保留
受控制的內容VM 的整體狀態(暫時性)VM 的密鑰暴露面(假憑證、傳輸邊界)

編碼工作需要持久性狀態——複製的儲存庫、套件快取、虛擬環境、shell 歷史——所以在每次工作階段後銷毀 VM 會讓代理程式毫無用處。Bromure Agentic Coding 並不控制 VM 的狀態,而是控制 VM 究竟被允許持有什麼:沒有真實密鑰,也沒有通往網際網路的未經仲介路徑。暫時性仍然存在,但作為一種逃生口而非預設值:重設磁碟會從基底映像檔重新複製系統磁碟,磁碟與家目錄檢查點允許回復,bromure-cli vm run --rm 建立在 VM 停止時刪除的 docker 風格用完即丟工作區,而入侵處置流程則會抹除受污染的磁碟與家目錄,同時保留你的設定與金鑰。

瀏覽器附屬 VM

Bromure(Web)的其中一塊在 Bromure Agentic Coding 內延續了下來:代理式瀏覽器窗格。當你(或代理程式)開啟它時,工作區會得到第二個暫時性 VM——一個複製到臨時目錄、並在窗格拆除時刪除的 Alpine + Chromium 客體。這個附屬 VM 是「例外恰好證明規則」:瀏覽狀態預設可拋棄(除非工作區啟用保持登入網站,這會將 Chromium 的設定檔保存在各工作區專屬的加密磁碟上),而它旁邊的工作區 VM 則是持久的。兩個 VM 都位於同一個私有網路區段,因此瀏覽器可以透過 VM 的 IP 載入代理程式剛啟動的開發伺服器。

VM 生命週期:關閉、暫停與執行中

每個工作區始終恰好處於三種持久狀態之一,在側邊欄工作區名稱旁與 VM 儀表板上以膠囊標籤顯示。(在 VM 正在啟動時,你也會短暫看到瞬時狀態——側邊欄中的啟動中…,以及儀表板上的開機指示。)

工作區瀏覽器顯示一個已停止的工作區:關閉膠囊標籤、CPU、記憶體、vCPUs、磁碟與運作時間卡片、CONFIGURATION 摘要,以及啟動按鈕

選取工作區的名稱會在任何狀態下顯示其儀表板:執行中時顯示即時的 CPU、記憶體、vCPU、磁碟與運作時間卡片,或在關閉或暫停時顯示機器的規格與設定摘要——上方的螢幕截圖顯示一個從未啟動過的工作區,這就是為什麼磁碟卡片仍顯示 0 MB(尚無複製體存在)。右上角的按鈕在關閉的工作區上是啟動,在暫停的工作區上是恢復

狀態VM 的情況…保留消失
關閉完全未執行。沒有記憶體、沒有程序。系統磁碟(disk.img)、家目錄(home.img)、檢查點、工作區設定、SSH 金鑰、MAC/IP 繫結。執行中的程序、RAM 內容、終端機分頁、任何已儲存的 RAM 快照(乾淨關機會將其清除,因此下次啟動為冷開機)。
暫停凍結。其 RAM 已寫入工作區目錄中的 vm.state,分頁配置寫入 tabs.json關閉所保留的一切,外加每個執行中的程序、開啟的檔案與終端機分頁——恢復時會將工作階段完全還原到離開時的狀態,近乎瞬間完成。沒有,除非快照必須捨棄(見下文)。
執行中運作中。工作階段視窗可能已連接,或 VM 可能在背景以無介面方式執行。一切都是即時的。

有幾條值得內化的生命週期規則:

  • 暫停是 RAM 快照,不是存檔。 還原它需要 VM 的設定完全相同,這就是為什麼每個工作區都會持久保存機器識別碼與確定性 MAC 位址。如果你在快照存在時變更共用資料夾集合,應用程式會詢問是否捨棄暫停狀態——下次啟動為冷開機,且不會影響任何檔案。
  • 快照絕不會比其磁碟存活得更久。 重設或抹除系統磁碟同時也會捨棄任何已儲存的 RAM 快照與分頁狀態,因為全新磁碟加上陳舊 RAM 會立即損毀。
  • 關閉不代表抹除。 已關機的工作區會無限期保留其系統磁碟與家目錄。實際的資料銷毀始終是明確的(重設磁碟抹除家目錄刪除工作區)或由入侵處置流程強制執行。

關閉動作

當你關閉工作階段時發生什麼是各工作區的選擇(工作區編輯器中的關閉視窗時):在背景執行(分離視窗,讓 VM 繼續執行)、暫停關機詢問——預設值,每次都以全部三個選項提示。關閉最後一個終端機分頁會經由同一個選擇處理。完整流程請參閱工作階段

傳輸邊界

傳輸邊界是產品的核心理念:來自客體的所有對外 HTTPS 都會通過主機端的中間人(MITM)代理伺服器,而每一項防護——保密、憑證範圍限定、供應鏈掃描、提示注入偵測、追蹤——都在那一個位置強制執行。代理程式無法繞過它,因為在它那一側的界線上沒有任何有用的東西。

端到端的流程:

  1. 客體只持有假憑證。 在工作階段啟動時,主機會將刻意設為無效的預留位置憑證寫入 VM——諸如 ANTHROPIC_API_KEY 的環境變數,以及諸如 ~/.git-credentials~/.docker/config.json~/.kube/config 的設定檔。假憑證保留結構(sk-ant-api03-brm-…ghp_… 形狀、brm_…),以便用戶端驗證器接受它們,並且每次安裝皆為確定性,因此工具絕不會在工作階段之間看到金鑰「輪替」。相符的真實值會載入主機上代理伺服器的記憶體內置換對映表,每個都以其所屬的目的地主機為鍵。
  2. 客體的 TLS 在代理伺服器終止。 客體中的每個 shell 都匯出 HTTPS_PROXY=http://127.0.0.1:8080,這是一個 VM 內端點,透過 vsock(連接埠 8443)通道連往主機代理伺服器。代理伺服器提供一份由 Bromure 根 CA 簽署的偽造各主機專屬葉憑證,檢查請求,並重新加密後送往真正的上游。
  3. 假憑證只在送出途中才變成真實憑證。 代理伺服器將每個假憑證換成其真實值——API 金鑰與權杖採標頭置換,OAuth 更新流程採主體置換,AWS 採完整的 SigV4 重新簽署(客體以假密鑰簽署;主機剝除該簽章並以真實密鑰重新簽署),SSH 採透過 vsock 的 ssh-agent 簽署。置換的範圍限定為完全相符或子網域符合已註冊的主機,絕不採子字串比對,因此為 api.anthropic.com 註冊的憑證絕不會被注入到外觀相似的網域。

Bromure 根 CA

代理伺服器之所以能終止客體的 TLS,只是因為客體信任它這麼做。在首次啟動時,應用程式會產生一個各安裝專屬的憑證授權單位——Bromure Agentic Coding 根 CA——其公開憑證會在開機時透過中繼共用區掛載到每個 VM 的信任存放區。私鑰絕不離開主機(它位於 ~/Library/Application Support/BromureAC/ca/ 下,僅擁有者可讀)。你的 Bromure VM 之外沒有任何東西信任此 CA:它無法用來攔截你 Mac 自身的流量,而刪除 ca/ 目錄只會在下次啟動時鑄造一個全新的 CA。

設計上即為故障關閉

此設計為故障關閉(fail-closed):如果客體流量曾繞過代理伺服器——某個忽略代理變數的工具、原始通訊端、刻意的繞過嘗試——它唯一能提供的憑證就是沒有任何上游會接受的假憑證。AWS 會傳回 InvalidSignatureException;API 供應商會拒絕該預留位置金鑰。繞過此邊界對攻擊者毫無所得,因為此邊界不是檢查密鑰的地方——它是密鑰存在的唯一地方。

入侵偵測器

此邊界也監看相反方向的濫用:外洩。代理伺服器會掃描每個對外請求,尋找工作區任何已註冊的假權杖。一個假憑證恰好只有一個合法目的地——它為之鑄造的主機——因此觀察到假憑證前往其他任何地方,就是代理程式試圖洩漏憑證的特徵。代理伺服器會拒絕該請求而不轉發一個位元組,暫停 VM,並向你發出警示;該工作區會被標記為已入侵,並在其(推定受污染的)磁碟與家目錄被抹除之前拒絕再次開機。你的設定、權杖與 SSH 金鑰都會保留——而由於只有假憑證曾洩漏,真實憑證從不需要輪替。完整的憑證模型,包括各憑證的核准提示與 TTL 限時授予,涵蓋於憑證與傳輸邊界

什麼會持久保存、什麼不會

Bromure Agentic Coding 對於存續期是明確的。工作區所擁有的一切都位於 ~/Library/Application Support/BromureAC/profiles/<uuid>/ 下;下方的表格是何者在何種情況下存續的權威對照圖。

持久性——在關機與應用程式重新啟動後存續:

項目位置附註
系統磁碟disk.img基底映像檔的 APFS CoW 複製體。在關機後存續;由重設磁碟刪除工作區或入侵抹除移除。
家目錄home.img(舊式:home/保存 /home/ubuntu。在關機與重設磁碟後存續。
回復檢查點checkpoints/checkpoints/home/磁碟與家目錄的開機驗證快照,採分層保留。
工作區設定profile.json非密鑰設定;真實憑證另行儲存,在主機上加密。
SSH 金鑰ssh/工作區的金鑰對(僅以簽章形式透過 vsock 提供給客體)。
機器身分machine-identifier.bin 加上 profile-macs.json 中的 MAC 繫結讓 VM 的身分(通常還有其 IP)跨啟動保持穩定;還原暫停快照時必需。
暫停快照vm.state 加上 tabs.json僅在工作區處於暫停時;由乾淨關機清除。
瀏覽器設定檔(選擇性加入)browser-profiles/<uuid>/image/僅在啟用保持登入網站時;各工作區專屬加密。

暫時性——自動重建或銷毀:

項目存續期
中繼共用區內容(meta-share/:假權杖環境檔、代理設定、CA 憑證、客體代理)在每次開機時重建。
寄件匣事件(outbox/每次啟動。
瀏覽器附屬 VM 磁碟(臨時目錄中的 CoW 複製體)在瀏覽器窗格拆除時刪除。
憑證核准授予與拒絕僅在記憶體中;在工作階段拆除時撤銷。
客體 RAM、程序、終端機分頁除非暫停,否則在關機時遺失。

從這張對照圖得出兩個結果。首先,「關閉視窗」本身絕不具破壞性——具破壞性的動詞全部都是明確且需確認的。其次,當你想要可拋棄性時,你有分級選項:回復某個檢查點、重設磁碟(家目錄存續)、抹除家目錄、刪除工作區,或一開始就用 bromure-cli vm run --rm 以用完即丟的方式啟動。

附註: 共用主機資料夾是你 Mac 上的專案目錄,位於 Bromure 的儲存之外。它們絕不會被任何 Bromure 動作抹除——包括入侵抹除——而抹除提示也會明確如此說明。

主機—客體橋接(vsock)

Mac 與客體之間的互動式整合乘載於 virtio 通訊端上——點對點的主機對客體通道,獨立於 VM 的網路而存在。你永遠不需要設定這些,但知道它們存在有助於閱讀追蹤記錄或疑難排解章節。每個橋接都在一個編號的 vsock 連接埠上監聽:

工作區 VM 橋接:

連接埠橋接它承載什麼
8443MITM 代理伺服器所有客體 HTTPS——傳輸邊界本身。
8444ssh-agent 橋接來自客體 SSH_AUTH_SOCK 的簽章請求;私鑰位元組絕不越界。
8445AWS 憑證輔助程式credential_process 饋送(真實存取金鑰 ID、假密鑰)。
8446Claude 權杖代理/本機推論Claude 的訂閱權杖植入,以及客體對主機的本機推論橋接(此連接埠由兩者共用)。
8447Codex 權杖代理Codex 的訂閱權杖植入。
5800Shell 執行代理終端機連接路徑、bromure-cli exec、檔案瀏覽器視窗、檔案總管窗格,以及影像貼上上傳。
5010OAuth 回呼中繼迴路 OAuth 重新導向(用於 ghgcloud 及類似登入),送回 VM 內的 CLI。
5830瀏覽器 MCP 墊片將代理程式的瀏覽器自動化 MCP 伺服器連接到主機。

瀏覽器附屬 VM 橋接: 設定(5000)、檔案傳輸(5100)、Chrome DevTools Protocol(5200)、連結中繼(5300)、網路攝影機(5400)、原生分頁列(5810),以及網路追蹤(5900)。

剪貼簿

工作區終端機沒有獨立的剪貼簿常駐程式——剪貼簿乘載於終端機協定本身。在客體內複製(tmux 選取,或任何發出 OSC 52 的程式)會自動落到 macOS 剪貼板上;⌘C 複製主機端的終端機選取;⌘V 使用括號式貼上將內容貼入客體。在瀏覽器窗格中,一個客體剪貼簿代理加上攔截的 ⌘C/⌘V 提供 Mac 與 Chromium 之間的複製與貼上。

檔案傳輸

檔案在 Mac 與工作區之間有三種移動方式,全部涵蓋於工作階段:共用資料夾(virtiofs,專案檔案的正常路徑)、類似 Finder 的檔案瀏覽器視窗(透過連接埠 5800 上的 vsock 檔案服務拖入與拖出),以及影像貼上(⌘V 搭配影像會將其上傳進客體並貼上其路徑)。連接埠 5100 上的專用檔案傳輸協定屬於瀏覽器附屬 VM。

網路

NAT 模式(預設)

NAT 模式下的所有工作區 VM 都連接到單一的整個程序範圍軟體 L2 交換器,多工到一個 vmnet 共用/NAT 介面上。其後果:

  • 一個私有子網路——預設為 192.168.64.0/24(閘道 .1,位址從 .2.254 租用 24 小時)。如果你 Mac 自己的 LAN 已使用該範圍,Bromure 會自動挑選另一個 192.168.x.0/24
  • Bromure 執行自己的 DHCP 伺服器於該交換器上(Apple 內建的每個介面只能追蹤單一租約),而租約持久保存於主機上的 dhcp-leases.sqlite
  • 穩定的定址——每個工作區都會得到一個持久保存於 profile-macs.json 的確定性、本機管理的 MAC 位址,結合持久性租約,工作區通常會在應用程式重新啟動後保持相同的 IP(盡力而為:只要該位址仍空閒即可)。目前的 IP 始終顯示在 VM 儀表板標頭與工具列膠囊標籤中。
  • VM 可以彼此互達。 NAT 模式下的每個 VM——工作區 VM 與瀏覽器附屬 VM 皆是——在設計上都位於同一個 L2 區段上,因此瀏覽器窗格可以載入工作區 VM 中執行的開發伺服器,而兩個工作區也可以互相通訊彼此的服務。儀表板的「監聽連接埠」卡片會將每個可從外部連達的客體通訊端列為 <VM-IP>:<port> 端點,也就是你實際上會從 Mac 連接的位址。
  • 與外界隔離。 NAT 表示這些 VM 可從你的 Mac 連達,但不會暴露在你的實體 LAN 上,且來自別處的入站連線是不可能的,除非你明確發佈某個服務(各服務專屬的 Cloudflare 快速通道,從「監聽連接埠」卡片)。

客體網路卡的 MTU 預設鉗制在 1280——這是一個能在 VPN 與企業路徑 MTU 環境中存活的保守值——可用 defaults write io.bromure.agentic-coding vm.mtu -int <value> 提高。

請記住,此網路上的一般 IP 流量並不是憑證流動的方式:客體 HTTPS 會被導向 VM 內的代理端點,並透過 vsock 前往傳輸邊界。NAT 網路承載其他一切——而任何繞過代理伺服器的東西只承載假憑證,這正是上文所述的故障關閉特性。

橋接模式(各工作區)

工作區也可以改為加入你的實體 LAN:橋接模式透過 vmnet 橋接將 VM 連接到選定的主機介面,使其顯示為本機網路上的一個裝置(當其他機器必須直接連達 VM 時很有用)。如果選定的介面在啟動時無法使用,VM 會回退到 NAT。網路模式在工作區編輯器中各工作區各別設定;請參閱工作區

即時啟動與預熱

有兩種不同的機制讓工作階段感覺起來是即時的,值得知道各自適用於何處:

  • 工作區 VM 不採集區池化。 每個工作區直接開機自己的持久性 VM。首次啟動之所以快,是因為系統磁碟是即時的 CoW 複製體而非複製的映像;後續的冷開機是一般的 Linux 開機(由動畫開機覆蓋層涵蓋);而暫停的工作區則完全跳過開機——它的 RAM 快照會被還原,工作階段就地恢復,連同終端機在內,近乎瞬間完成。
  • 瀏覽器附屬 VM 使用暖池。 引擎會在背景保持一個預先開機的瀏覽器 VM 待命,因此開啟代理式瀏覽器窗格花不到 1 秒。當該 VM 被取用時,一個替補 VM 開始預熱;閒置期間,暖 VM 的記憶體氣球會被充氣(客體大約保留 512 MB),且該 VM 在 30 秒後暫停以維持低成本,然後在取用時恢復並將氣球洩氣(將完整記憶體還原給客體)。

這項區別直接源自生命週期理念:池化的 VM 只有在每個執行個體都可互換時才合理,這對用完即丟的瀏覽器 VM 為真,對持久的各工作區專屬機器為假。