MINARA
安全

審計與覆蓋

每次閘門決策都會寫入日誌。受信任的工作流可在策略層豁免。緊急停止開關用於事故響應,始終留下操作記錄。

上週一,你嘗試運行的某個腳本被攔截了。隱約記得點過"取消",但具體是哪個腳本?又或者,你有一條從頭到尾經過審查的自動化流程,每次運行時卻仍會彈出同樣的確認問題。能不能讓閘門直接放行?

本頁介紹三個操作員級別的控制手段:查看歷史決策、配置單工作流豁免,以及緊急停止開關。

設計理念:可見、可攔截、始終審計

以下三條屬性貫穿閘門的每條代碼路徑:

  1. 可見。 每次閘門決策(拒絕 / 確認 / 放行)都會寫入一條審計記錄,無一例外。操作員可隨時回溯。
  2. 可攔截。 受信任的工作流可通過 script_risk_policy 預先批准特定腳本體。豁免本身也會寫入一條審計記錄,可區分"因策略獲批"與"腳本本身乾淨"這兩種情況。
  3. 始終審計。 就算在事故響應期間設置了 DISABLE_SCRIPT_RISK_GATE=1,每次被旁路的調用也會寫入一條標記 bypassed_by="env_global" 的記錄。任何使用模式都不會讓閘門保持沉默。

為什麼這樣設計? 信任來自透明,而非單純的嚴格。只會攔截的閘門最終會被繞過:有人設置了那個環境變量然後忘記了。一個提供清晰旁路路徑、同時記錄每次使用的閘門,既足夠靈活(真實工作流可以順利運行),也保持問責(事故發生後可以還原現場)。

查看決策記錄:minara script-risk list / show

先從"今天剛發生了什麼"入手:

# 所有工具最近 50 条决策
minara script-risk list

# 最近 24 小时内的拒绝记录
minara script-risk list --verdict=reject --since=2026-05-14

# 特定会话的所有决策
minara script-risk list --session=abc-123

# 特定工作流定义内的所有决策
minara script-risk list --workflow=wf_daily_rebalance

# 按工具过滤
minara script-risk list --tool=execute_code

# 查看某条决策的完整详情(所有 finding、所有证据行)
minara script-risk show <decision-id>

# 机器可读格式
minara script-risk list --verdict=confirm --json

各標誌可組合使用。目的是取證:當你想了解昨天哪些腳本被攔截時,從寬泛的 --verdict=reject 開始,再逐步縮小範圍(--session--workflow--tool--since)。

HTTP 等效接口提供相同的數據結構:

GET /v1/admin/script-risk/decisions?verdict=reject&tool=terminal&since=…&limit=…
GET /v1/admin/script-risk/decisions/<id>

如果你把網關暴露給除自己以外的人,請在反向代理層對該接口加以保護。

審計記錄包含什麼、不包含什麼

每條決策都會記錄:

  • 決策時間戳、工具名稱、工具調用 ID(已知時)、會話 ID
  • 裁定(拒絕 / 確認 / 放行)及 findings 數組;每個 finding 包含類別、單行描述、屏蔽後的證據文本,以及在腳本體中的行號
  • body_sha256:被分析腳本體的哈希值
  • user_decision(execute / cancel / timeout):當流程經過確認彈窗時記錄
  • bypassed_by(env_global / workflow_policy / null):當流程通過顯式策略放行時記錄

明確不記錄:

  • 腳本體本身
  • 匹配到脫敏規則的原始私鑰、Authorization 頭、Cookie 值或 Bearer token
  • 腳本的 stdout / stderr

為什麼不記錄完整腳本體? 含有私鑰的腳本一旦持久化,審計日誌就變成了第二條洩漏通道。存儲 sha256 可以回答"之前是否見過這個腳本?"(是/否);屏蔽後的證據可以回答"哪條規則觸發了、匹配的內容大致是什麼?";兩者都不需要把密鑰複製到長期存儲的表中。

代價是:事後無法逐字節回放腳本體。換來的是一份可以安全備份、共享和 grep 的審計日誌。

工作流豁免:script_risk_policy

典型場景是這樣的:你有一個定投 (DCA) 工作流,每天調用 minara swap USDC ETH 100。腳本是你自己寫的,也經過了審查,體內容不會變化。每次運行都要確認,純屬摩擦。

在工作流定義內配置:

script_risk_policy:
  approved_body_sha256:
    - "abc123…"      # 你审查过的脚本的 sha256
  allowed_categories:
    - fund_moving_cli  # 该工作流被明确允许
                       # 调用 minara swap

通過 workflow_activate 激活工作流(該操作本身是涉及資金的兩步確認)後,策略即註冊生效。此後,當該工作流運行匹配的腳本體時,YELLOW 級別的 finding 會靜默降級。審計記錄中會寫入 bypassed_by="workflow_policy",事後仍可看出閘門未攔截的原因。

適用場景:

  • 體內容穩定的預審腳本(哈希校驗將你鎖定在特定版本)
  • 特定業務工作流中,某類已知操作本就是其核心目的(閃兌的定投工作流;調用 approve 的再平衡工作流)

不適用場景:

  • 通用的萬能工作流。策略應足夠精確,一句話就能說清楚"這條豁免是為什麼而設"。
  • 對所有類別全部放行。那等於對一個工作流徹底關閉閘門。
  • 每次運行時動態生成體內容的腳本。體內容變化後 sha256 不匹配,策略會靜默失效(失敗時保持關閉,本身沒問題,但你增加了複雜度卻毫無收益)。

為什麼策略可以旁路 YELLOW 而不能旁路 RED? YELLOW 表示"合理但有風險":minara swap 是真實的操作,確實有人可能想自動化它。策略正是用來表達"是的,這個特定工作流被允許執行該類操作"的。

RED 表示"沒有合理的業務理由"。批量刪除、IMDS 數據外洩、內聯私鑰,這些情況不存在合法的工作流場景。如果你的工作流觸發了 RED,解決辦法是修改工作流腳本,而非放寬策略。RED 被設計為策略不可旁路。

全局緊急停止開關:DISABLE_SCRIPT_RISK_GATE

設置環境變量 DISABLE_SCRIPT_RISK_GATE=1 會完全跳過閘門,RED 和 YELLOW 均直接放行。每次旁路仍會寫入一條審計記錄,標記 bypassed_by="env_global"

每年應僅使用數次的場景:

  • 生產事故響應。 一個真實的誤報正在阻斷正常業務,需要十分鐘時間發佈修復。設置環境變量、完成恢復操作、取消設置,然後提交 issue 收緊觸發規則。
  • 完全隔離的 CI。 回測、端到端測試、迴歸測試套件;所有調用方可證明為非交互式,測試環境處於沙盒中。

永遠不應使用的場景:

  • "確認彈窗太煩了":那正是安全機制在發揮作用。
  • "我在給團隊運行 agent,不想審查策略":這會讓整個團隊暴露在攻擊者能繞過第一層防禦的風險中。
  • 寫進 shell profile 然後忘記。下一個無關的會話會繼承它。

從審計角度,可以這樣發現濫用:

minara script-risk list --json \
  | jq '.decisions[] | select(.bypassed_by == "env_global")'

如果在你記憶中的時間窗口之外看到 env_global 旁路記錄,說明環境變量在某處被設置了,而你並沒有意識到。

完整環境變量參考見環境變量 → DISABLE_SCRIPT_RISK_GATE

操作員職責

第 4 層(閘門)、第 3 層(涉及資金的確認)和第 2 層(OS jail)承擔了大量工作,但無法替代一些不可省略的操作員規範:

  • 每個 Minara 實例對應一名操作員。 Minara 為單用戶交易場景設計,不支持多租戶 SaaS。團隊共享的 Web UI 不在支持範圍內;每位操作員應運行自己的實例。
  • 私鑰存放在 .env 中,不進代碼庫。.env 應設置為 chmod 600。閘門可以在運行時阻止第 4 層讀取未授權文件,但無法阻止你在 shell 中執行 cat .env
  • 看到 RED 時,不要嘗試旁路。 停下來想想:為什麼自己運行的腳本觸發了高置信度的惡意模式?95% 以上的情況不是誤報,那是閘門在履職。
  • 看到 YELLOW 時,閱讀證據。 花兩秒鐘讀一下匹配行,這正是彈窗存在的意義。憑肌肉記憶點"執行",只會讓自己成為最薄弱的一環。
  • 永遠不要把 MINARA_SKIP_FUND_CONFIRM=1DISABLE_SCRIPT_RISK_GATE=1 寫入 .zshrc.envrc 或 systemd unit。 如果某個腳本確實需要,就為那條命令單獨內聯設置,完成後立即取消。
  • 審計日誌的備份很重要。 script_risk_decisions SQLite 表是取證鏈的一部分,應像對待日誌一樣對待它。

本頁目錄