SoyaOS

能力與沙箱

Comet 怎麼強制一個 Agent 能做什麼、不能做什麼。

SoyaOS 裡的每個 Agent 都跑在 Comet 沙箱裡,受能力白名單約束。任何沒在 capabilities 裡宣告的事都被拒絕。模型是 fail-closed:預設狀態是「你碰不到外部世界」,清單按需開口子。

為什麼要能力模型

三股壓力推出這個模型:

  1. 作者不可信。 SoyaPack 可能來自任何地方。你昨天 pull 的一個套件,今天作者翻臉要導你資料時,它應該沒這個本事。
  2. 稽核可信。 出事時,你想看一眼一份 YAML 裡的一個區塊就回答「這個套件當時能訪問什麼」,而不是去爬 Go 程式碼。
  3. 可重現。 能力宣告同時是 Comet 快取的合約:egress: [] + determinism_tier: read-only 的套件,可證明是可快取的。

什麼被守住

表面機制能繞過嗎?
網路出網按 host:port:protocol 三元組白名單;執行時解析不能——DNS 解析本身也走白名單。
檔案系統讀mount namespace + bind mount,按前綴比對不能——白名單外的路徑是 404。
檔案系統寫同讀;fs.write 外的寫入 EACCES不能。
行程 exec只允許套件自己的直譯器;spawn 子行程被拒不能。
時間訪問讀實時時鐘(clock_gettime)允許;設置時間不允許n/a——日誌要用。
隨機數/dev/urandom 永遠可用n/a。
DNS 出站透過 Moon 解析(Moon 強制白名單)不能。

Egress

capabilities:
  egress:
    - host: api.openai.com
      port: 443
      protocol: https
    - host: hooks.slack.com
      port: 443
      protocol: https
  • 每條是三元組——host + port + protocol——三者都比對才能連通。
  • 接受萬用字元(*.openai.com),但 pack lint --strict 會標紅。
  • 接受 IP 直寫(192.168.1.1),但不鼓勵——服務遷移就壞了。
  • Egress 在 Comet 內部強制;即使你的工具用裸 socket 想繞,Comet 啟動時設的核心 netfilter chain 也會攔下。

如果你的套件確實需要不固定數量的主機(比如爬蟲 Agent),有兩個老實的選擇:

  • unrestricted + egress: ["*"] ——明說自己是黑盒。Comet 拒絕快取結果。
  • 加一個 Moon 端代理——只把 Moon 的 HTTP 代理放進 egress;Moon 自己再持一份白名單。生產推薦。

檔案系統

capabilities:
  fs:
    read:
      - /workdir          # 總是可用;顯式寫出來更清晰
      - /workdir/inputs
    write:
      - /workdir/out
  • 所有路徑都是沙箱內部的。宿主檔案系統不可見——Comet 啟動時建一個全新的 mount namespace。
  • 前綴比對。/workdir/out/foo.jsonfs.write: [/workdir/out] 下放行。
  • /workdir 本身預設唯讀,除非你把某個子路徑列入可寫。
  • 讀未宣告的路徑回傳 ENOENT 而不是 EACCES——也就是「這檔案不存在」。故意的:永不洩漏宿主目錄結構。

確定性層級

層級語意快取?
read-only相同輸入總是產生相同輸出(上游 LLM 非確定性除外)。是,按輸入 hash。
side-effectAgent 在沙箱外產生可觀測變化(建 Linear issue、發 Slack、寫資料庫)。否。
unrestricted逃生口。把 Agent 當完全黑盒。隱含 side-effect否。

層級是按 Agent 的行為而不是僅按宣告強制的。如果一個 Agent 宣告 read-onlytools 裡有 kind: builtin.http_post,push 時校驗失敗。

違規會怎麼樣

Comet 偵測到能力越界(網路、fs、exec)時:

  1. 當前 syscall 回傳 EACCES / ENOENT / ECONNREFUSED——Agent 程式碼看到的是「正常」錯誤。
  2. 發一條 capability_violation 的 Scope 事件,含違規表面、申請資源、比對的清單條目(或「無比對」)。
  3. 執行以結束碼 3 結束。
  4. Moon 在倉庫裡給該套件版本打標;後續相同版本的呼叫每次都警告,直到套件被修。

CI 裡:

$ soyaos pack lint . --strict
err   capabilities.egress 宣告了 `api.openai.com:443` tools.fetch 用的是 `api.anthropic.com:443`
1 error · 0 warnings

工具支援

  • soyaos pack validate . ——校驗清單形狀。
  • soyaos pack lint . ——校驗 capabilitiestoolsexamples 之間的一致性。
  • soyaos pack lint . --strict ——萬用字元主機、宣告了但沒範例覆蓋的能力、determinism_tier 不比對,都失敗。

清單 schema 見 SoyaPack v0 清單;事件 envelope 見 Scope 事件

在 GitHub 上編輯本頁