跳到主要內容

安全性

Hermes Agent 採用縱深防禦(defense-in-depth)的安全模型設計。本頁涵蓋所有安全邊界——從命令審批到容器隔離,再到消息平臺上的用戶授權。

概述

該安全模型包含七個層級:

  1. 用戶授權 —— 誰可以與 Agent 通信(白名單、私信配對)
  2. 危險命令審批 —— 破壞性操作需人工介入
  3. 容器隔離 —— 使用 Docker/Singularity/Modal 進行沙箱化,配置強化
  4. MCP 憑據過濾 —— MCP 子進程的環境變量隔離
  5. 上下文文件掃描 —— 項目文件中的提示注入檢測
  6. 跨會話隔離 —— 會話之間無法訪問彼此的數據或狀態;定時任務存儲路徑經過加固,防止路徑遍歷攻擊
  7. 輸入淨化 —— 終端工具後端的工作目錄參數會根據白名單進行驗證,防止 shell 注入

危險命令審批

在執行任何命令之前,Hermes 會將其與一個精心維護的危險模式列表進行比對。若匹配成功,則必須由用戶顯式批准。

審批模式

審批系統支持三種模式,通過 ~/.hermes/config.yaml 中的 approvals.mode 配置:

approvals:
mode: manual # 手冊|聰明|離開
timeout: 60 # 等待用戶響應的秒數(默認值:60)
模式行為
manual(默認)對所有危險命令始終提示用戶確認
smart使用輔助 LLM 評估風險。低風險命令(如 python -c "print('hello')")自動批准。真正危險的命令自動拒絕。不確定的情況升級為人工提示。
off禁用所有審批檢查——等同於使用 --yolo 運行。所有命令無提示直接執行。
注意

approvals.mode: off 設置為關閉狀態會禁用所有安全提示。僅在可信環境(CI/CD、容器等)中使用。

YOLO 模式

YOLO 模式會繞過當前會話中所有危險命令的審批提示。可通過以下三種方式激活:

  1. CLI 標誌:使用 hermes --yolohermes chat --yolo 啟動會話
  2. 斜槓命令:在會話中輸入 /yolo 切換開啟/關閉
  3. 環境變量:設置 HERMES_YOLO_MODE=1

/yolo 命令是一個切換開關——每次使用都會在開啟與關閉之間切換:

> /yolo
⚡ YOLO mode ON — all commands auto-approved. Use with caution.

> /yolo
⚠ YOLO mode OFF — dangerous commands will require approval.

YOLO 模式在 CLI 和網關會話中均可用。內部通過設置 HERMES_YOLO_MODE 環境變量實現,該變量在每次命令執行前被檢查。

危險

YOLO 模式會禁用會話期間所有危險命令的安全檢查。僅在完全信任所生成命令時使用(例如在可丟棄環境中運行經過充分測試的自動化腳本)。

審批超時

當出現危險命令提示時,用戶有可配置的時間窗口進行響應。若在超時時間內未作出響應,命令將默認拒絕(關閉失敗)。

~/.hermes/config.yaml 中配置超時時間:

approvals:
timeout: 60 # 秒(默認值:60)

觸發審批的條件

以下模式會觸發審批提示(定義於 tools/approval.py):

模式描述
rm -r / rm --recursive遞歸刪除
rm ... /在根路徑下刪除
chmod 777/666 / o+w / a+w全局/其他用戶可寫權限
chmod --recursive 攜帶不安全權限遞歸設置全局/其他用戶可寫(長選項)
chown -R root / chown --recursive root遞歸更改所有者為 root
mkfs格式化文件系統
dd if=磁盤複製
> /dev/sd寫入塊設備
DROP TABLE/DATABASESQL DROP
DELETE FROM(無 WHERE)SQL DELETE 無 WHERE 條件
TRUNCATE TABLESQL TRUNCATE
> /etc/覆蓋系統配置
systemctl stop/disable/mask停止/禁用系統服務
kill -9 -1殺死所有進程
pkill -9強制終止進程
Fork bomb 模式Fork bomb
bash -c / sh -c / zsh -c / ksh -c通過 -c 標誌執行 shell 命令(包括組合標誌如 -lc
python -e / perl -e / ruby -e / node -c通過 -e/-c 標誌執行腳本
curl ... | sh / wget ... | sh將遠程內容管道傳遞給 shell
bash <(curl ...) / sh <(wget ...)通過進程替換執行遠程腳本
tee 寫入 /etc/~/.ssh/~/.hermes/.env通過 tee 覆蓋敏感文件
> / >> 寫入 /etc/~/.ssh/~/.hermes/.env通過重定向覆蓋敏感文件
xargs rmxargs 攜帶 rm
find -exec rm / find -deletefind 帶有破壞性操作
cp/mv/install 寫入 /etc/複製/移動文件至系統配置目錄
sed -i / sed --in-place 修改 /etc/在系統配置上進行就地編輯
pkill/killall hermes/gateway防止自我終止
gateway run 攜帶 &/disown/nohup/setsid防止網關在服務管理器外啟動
信息

容器繞過:當在 dockersingularitymodaldaytona 後端運行時,危險命令檢查將被跳過,因為容器本身即是安全邊界。容器內的破壞性命令無法對宿主機造成損害。

審批流程(CLI)

在交互式 CLI 中,危險命令會顯示內聯審批提示:

  ⚠️  DANGEROUS COMMAND: recursive delete
rm -rf /tmp/old-project

[o]nce | [s]ession | [a]lways | [d]eny

Choice [o/s/a/D]:

四個選項:

  • once — 僅允許本次執行
  • session — 允許此模式在當前會話剩餘時間內持續生效
  • always — 添加到永久允許列表(保存至 config.yaml
  • deny(默認)— 阻止該命令

審批流程(網關/消息平臺)

在消息平臺中,Agent 會將危險命令詳情發送至聊天,並等待用戶回覆:

  • 回覆 yesyapproveokgo 以批准
  • 回覆 nondenycancel 以拒絕

運行網關時,HERMES_EXEC_ASK=1 環境變量會自動設置。

永久允許列表

使用“always”批准的命令將保存至 ~/.hermes/config.yaml

# 永久允許危險的命令模式
command_allowlist:
- rm
- systemctl

這些模式會在啟動時加載,並在所有未來會話中靜默通過審批。

提示

使用 hermes config edit 命令可查看或從永久允許列表中移除模式。

用戶授權(網關)

運行消息網關時,Hermes 通過分層授權系統控制誰可以與機器人交互。

授權檢查順序

_is_user_authorized() 方法按以下順序進行檢查:

  1. 平臺級全允許標誌(例如 DISCORD_ALLOW_ALL_USERS=true
  2. 私信配對批准列表(通過配對碼批准的用戶)
  3. 平臺特定允許列表(例如 TELEGRAM_ALLOWED_USERS=12345,67890
  4. 全局允許列表GATEWAY_ALLOWED_USERS=12345,67890
  5. 全局全允許GATEWAY_ALLOW_ALL_USERS=true
  6. 默認:拒絕

平臺允許列表

~/.hermes/.env 中以逗號分隔的值設置允許的用戶 ID:

# 特定於平臺的許可名單
TELEGRAM_ALLOWED_USERS=123456789,987654321
DISCORD_ALLOWED_USERS=111222333444555666
WHATSAPP_ALLOWED_USERS=15551234567
SLACK_ALLOWED_USERS=U01ABC123

# 跨平臺白名單(針對所有平臺進行檢查)
GATEWAY_ALLOWED_USERS=123456789

# 每個平臺允許全部(謹慎使用)
DISCORD_ALLOW_ALL_USERS=true

# 全局允許(謹慎使用)
GATEWAY_ALLOW_ALL_USERS=true
注意

如果未配置任何允許列表,且 GATEWAY_ALLOW_ALL_USERS 未啟用,則所有用戶均被拒絕。網關在啟動時會記錄警告:

No user allowlists configured. All unauthorized users will be denied.
Set GATEWAY_ALLOW_ALL_USERS=true in ~/.hermes/.env to allow open access,
or configure platform allowlists (e.g., TELEGRAM_ALLOWED_USERS=your_id).

私信配對系統

為實現更靈活的授權,Hermes 提供基於代碼的配對系統。無需提前提供用戶 ID,未知用戶將收到一個一次性配對碼,由機器人所有者通過 CLI 批准。

工作流程如下:

  1. 未知用戶向機器人發送私信
  2. 機器人回覆一個 8 位字符的配對碼
  3. 機器人所有者在 CLI 上運行 hermes pairing approve <platform> <code>
  4. 該用戶將被永久批准用於該平臺

~/.hermes/config.yaml 中控制未授權私信的處理方式:

unauthorized_dm_behavior: pair

whatsapp:
unauthorized_dm_behavior: ignore
  • pair 為默認行為。未授權的私信將收到配對碼回覆。
  • ignore 會靜默丟棄未授權的私信。
  • 平臺級配置會覆蓋全局默認設置,因此你可以在 Telegram 上保持配對功能,同時在 WhatsApp 上保持靜默。

安全特性(基於 OWASP 與 NIST SP 800-63-4 指南):

特性說明
代碼格式8 位字符,來自 32 位無歧義字母表(不含 0/O/1/I)
隨機性密碼學安全(secrets.choice()
代碼有效期1 小時過期
速率限制每用戶每 10 分鐘最多 1 次請求
待處理上限每平臺最多 3 個待處理代碼
鎖定機制5 次批准失敗 → 1 小時鎖定
文件安全所有配對數據文件設置 chmod 0600
日誌記錄代碼從不記錄到 stdout

配對 CLI 命令:

# 列出待處理和已批准的用戶
hermes pairing list

# 批准配對碼
hermes pairing approve telegram ABC12DEF

# 撤銷用戶的訪問權限
hermes pairing revoke telegram 123456789

# 清除所有待處理代碼
hermes pairing clear-pending

存儲位置:配對數據存儲在 ~/.hermes/pairing/ 目錄下,每個平臺對應 JSON 文件:

  • {platform}-pending.json — 待處理的配對請求
  • {platform}-approved.json — 已批准的用戶
  • _rate_limits.json — 速率限制與鎖定追蹤

容器隔離

使用 docker 終端後端時,Hermes 會對每個容器應用嚴格的安全部署加固。

Docker 安全標誌

每個容器均以以下標誌運行(定義於 tools/environments/docker.py):

_SECURITY_ARGS = [
"--cap-drop", "ALL", # 刪除 ALL Linux 功能
"--cap-add", "DAC_OVERRIDE", # 根目錄 可以寫入綁定安裝的目錄
"--cap-add", "CHOWN", # 包管理器需要文件所有權
"--cap-add", "FOWNER", # 包管理器需要文件所有權
"--security-opt", "no-new-privileges", # 阻止權限升級
"--pids-limit", "256", # 限制進程數
"--tmpfs", "/tmp:rw,nosuid,size=512m", # 大小限制 /tmp
"--tmpfs", "/var/tmp:rw,noexec,nosuid,size=256m", # 不執行 /var/tmp
"--tmpfs", "/run:rw,noexec,nosuid,size=64m", # 不執行 /run
]

資源限制

容器資源可在 ~/.hermes/config.yaml 中配置:

terminal:
backend: docker
docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
docker_forward_env: [] # 僅明確允許名單;空的將秘密保留在容器之外
container_cpu: 1 # CPU 核心
container_memory: 5120 # MB(默認 5GB)
container_disk: 51200 # MB(默認50GB,XFS上需要overlay2)
container_persistent: true # 跨 sessions 保留文件系統

文件系統持久化

  • 持久模式container_persistent: true):將 /workspace/root 綁定掛載自 ~/.hermes/sandboxes/docker/<task_id>/
  • 臨時模式container_persistent: false):使用 tmpfs 作為工作區 —— 清理時所有內容將丟失
提示

對於生產環境的網關部署,建議使用 dockermodaldaytona 後端,以將 Agent 命令與宿主機系統隔離。這將完全消除危險命令審批的需求。

注意

如果你在 terminal.docker_forward_env 中添加了變量名,這些變量會被有意注入容器中用於終端命令。這在傳遞任務專用憑據(如 GITHUB_TOKEN)時非常有用,但也意味著運行在容器中的代碼可以讀取並竊取這些憑據。

終端後端安全對比

後端隔離級別危險命令檢查適用場景
local無 — 在主機上運行✅ 是開發環境,可信用戶
ssh遠程機器✅ 是在獨立服務器上運行
docker容器❌ 跳過(容器本身即為邊界)生產網關
singularity容器❌ 跳過HPC 環境
modal雲沙箱❌ 跳過可擴展的雲隔離
daytona雲沙箱❌ 跳過持久化的雲工作區

環境變量透傳

execute_codeterminal 均會從子進程中剝離敏感環境變量,以防止由 LLM 生成的代碼導致憑據洩露。然而,聲明瞭 required_environment_variables 的技能需要合法訪問這些變量。

工作原理

兩種機制允許特定變量繞過沙箱過濾:

1. 技能範圍透傳(自動)

當通過 skill_view/skill 命令加載一個技能,並且該技能聲明瞭 required_environment_variables 時,環境中實際已設置的這些變量將自動註冊為透傳變量。尚未設置的變量(仍處於待配置狀態)不會被註冊。

# 在 Skill 的 `SKILL.md` frontmatter 中
required_environment_variables:
- name: TENOR_API_KEY
prompt: Tenor API key
help: Get a key from https://developers.google.com/tenor

加載該技能後,TENOR_API_KEY 將透傳至 execute_codeterminal(本地)、以及遠程後端(Docker、Modal) —— 無需手動配置。

Docker & Modal

在 v0.5.1 之前,Docker 的 forward_env 是與技能透傳獨立的系統。現在兩者已合併 —— 技能聲明的環境變量會自動轉發至 Docker 容器和 Modal 沙箱,無需手動添加到 docker_forward_env

2. 配置文件透傳(手動)

對於未被任何技能聲明的環境變量,可在 config.yaml 中添加至 terminal.env_passthrough

terminal:
env_passthrough:
- MY_CUSTOM_KEY
- ANOTHER_TOKEN

憑據文件透傳(OAuth 令牌等)

某些技能需要將文件(而不僅僅是環境變量)傳入沙箱中 —— 例如,Google Workspace 會將 OAuth 令牌存儲為活動配置文件的 HERMES_HOME 下的 google_token.json。技能在 frontmatter 中聲明這些文件:

required_credential_files:
- path: google_token.json
description: Google OAuth2 token (created by setup script)
- path: google_client_secret.json
description: Google OAuth2 client credentials

加載時,Hermes 會檢查這些文件是否存在於當前配置文件的 HERMES_HOME 中,並註冊它們以進行掛載:

  • Docker:只讀綁定掛載(-v host:container:ro
  • Modal:在沙箱創建時掛載,並在每次命令執行前同步(支持會話期間的 OAuth 設置)
  • 本地:無需操作(文件已可訪問)

你也可以在 config.yaml 中手動列出憑據文件:

terminal:
credential_files:
- google_token.json
- my_custom_oauth_token.json

路徑相對於 ~/.hermes/。文件將掛載到容器內的 /root/.hermes/

各沙箱的過濾規則

沙箱默認過濾規則透傳覆蓋
execute_code阻止名稱中包含 KEYTOKENSECRETPASSWORDCREDENTIALPASSWDAUTH 的變量;僅允許帶有安全前綴的變量通過✅ 透傳變量可繞過雙重檢查
terminal(本地)阻止顯式列出的 Hermes 基礎設施變量(提供者密鑰、網關令牌、工具 API 密鑰)✅ 透傳變量可繞過黑名單
terminal(Docker)默認不傳遞主機環境變量✅ 透傳變量 + docker_forward_env 通過 -e 傳遞
terminal(Modal)默認不傳遞主機環境變量或文件✅ 憑據文件掛載;環境變量通過同步傳遞
MCP僅允許安全系統變量 + 顯式配置的 env❌ 不受透傳影響(請使用 MCP 的 env 配置)

安全注意事項

  • 透傳僅影響你或你的技能顯式聲明的變量 —— 任意 LLM 生成代碼的默認安全策略保持不變
  • 憑據文件在 Docker 容器中以 只讀 方式掛載
  • Skills Guard 在安裝前掃描技能內容,檢測可疑的環境變量訪問模式
  • 未設置或缺失的變量不會被註冊(無法洩露不存在的內容)
  • Hermes 基礎設施密鑰(提供者 API 密鑰、網關令牌)絕不應添加到 env_passthrough —— 應使用專用機制處理

MCP 憑據處理

MCP(模型上下文協議)服務器的子進程接收一個過濾後的環境,以防止意外憑據洩露。

安全的環境變量

僅以下變量從主機傳遞到 MCP 標準輸入/輸出子進程:

PATH, HOME, USER, LANG, LC_ALL, TERM, SHELL, TMPDIR

以及所有 XDG_* 變量。其他所有環境變量(API 密鑰、令牌、密鑰)均被剝離

在 MCP 服務器的 env 配置中顯式定義的變量將被傳遞:

mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..." # 只有這個通過了

憑據脫敏

MCP 工具返回的錯誤消息在返回給 LLM 前會進行清理。以下模式將被替換為 [REDACTED]

  • GitHub PAT(ghp_...
  • OpenAI 風格密鑰(sk-...
  • Bearer 令牌
  • token=key=API_KEY=password=secret= 參數

網站訪問策略

您可以限制 Agent 通過其網絡和瀏覽器工具可訪問的網站。這有助於防止 Agent 訪問內部服務、管理面板或其他敏感 URL。

# 在“0”中
security:
website_blocklist:
enabled: true
domains:
- "*.internal.company.com"
- "admin.example.com"
shared_files:
- "/etc/hermes/blocked-sites.txt"

當請求被阻止的 URL 時,工具會返回錯誤信息,說明該域名因策略被阻止。黑名單規則適用於 web_searchweb_extractbrowser_navigate 以及所有支持 URL 的工具。

有關完整詳情,請參閱配置指南中的 網站黑名單

SSRF 防護

所有支持 URL 的工具(網絡搜索、網頁提取、視覺識別、瀏覽器)在獲取內容前都會驗證 URL,以防止服務器端請求偽造(SSRF)攻擊。被阻止的地址包括:

  • 私有網絡(RFC 1918):10.0.0.0/8172.16.0.0/12192.168.0.0/16
  • 環回地址127.0.0.0/8::1
  • 鏈路本地地址169.254.0.0/16(包含雲元數據服務 169.254.169.254
  • CGNAT / 共享地址空間(RFC 6598):100.64.0.0/10(Tailscale、WireGuard VPN 等)
  • 雲元數據主機名metadata.google.internalmetadata.goog
  • 保留地址、組播地址和未指定地址

SSRF 防護始終啟用,無法禁用。DNS 解析失敗被視為被阻止(故障關閉)。重定向鏈在每個跳轉點都會重新驗證,以防止通過重定向繞過。

Tirith 預執行安全掃描

Hermes 集成了 tirith 用於在命令執行前進行內容級掃描。Tirith 能檢測模式匹配無法識別的威脅:

  • 同形異義 URL 欺騙(國際化域名攻擊)
  • 管道注入解釋器模式(curl | bashwget | sh
  • 終端注入攻擊

Tirith 在首次使用時會從 GitHub 發佈版本自動安裝,並通過 SHA-256 校驗和驗證(若可用 cosign,則同時進行 cosign 證明驗證)。

# 在“0”中
security:
tirith_enabled: true # 啟用/disable tiith掃描(默認:true)
tirith_path: "tirith" # tirith 二進制文件的路徑(默認:PATH 查找)
tirith_timeout: 5 # 子進程超時(以秒為單位)
tirith_fail_open: true # 當 tiith 不可用時允許執行(默認值:true)

tirith_fail_opentrue(默認值)時,若 Tirith 未安裝或超時,命令仍將繼續執行。在高安全環境中,可將其設為 false,以在 Tirith 不可用時阻止命令執行。

Tirith 的判斷結果會集成到審批流程中:安全命令直接通過,而可疑或被阻止的命令則觸發用戶審批,並附帶完整的 Tirith 分析結果(嚴重性、標題、描述、更安全的替代方案)。用戶可選擇批准或拒絕——默認選擇為拒絕,以確保無人值守場景的安全性。

上下文文件注入防護

在將上下文文件(AGENTS.md、.cursorrules、SOUL.md)包含進系統提示前,會對其進行提示注入掃描。掃描內容包括:

  • 要求忽略/無視先前指令的指令
  • 包含可疑關鍵詞的隱藏 HTML 註釋
  • 嘗試讀取密鑰(.envcredentials.netrc
  • 通過 curl 進行憑證外洩
  • 不可見 Unicode 字符(零寬空格、雙向覆蓋字符)

被阻止的文件會顯示警告:

[BLOCKED: AGENTS.md contained potential prompt injection (prompt_injection). Content not loaded.]

生產部署的最佳實踐

網關部署檢查清單

  1. 設置明確的白名單 —— 生產環境中絕不要使用 GATEWAY_ALLOW_ALL_USERS=true
  2. 使用容器後端 —— 在 config.yaml 中設置 terminal.backend: docker
  3. 限制資源配額 —— 設置適當的 CPU、內存和磁盤限制
  4. 安全存儲密鑰 —— 將 API 密鑰保存在 ~/.hermes/.env 中,並設置正確的文件權限
  5. 啟用 DM 配對 —— 儘可能使用配對碼而非硬編碼用戶 ID
  6. 審查命令白名單 —— 定期審計 config.yaml 中的 command_allowlist
  7. 設置 MESSAGING_CWD —— 避免 Agent 在敏感目錄中運行
  8. 以非 root 用戶運行 —— 絕對不要以 root 身份運行網關
  9. 監控日誌 —— 檢查 ~/.hermes/logs/ 中是否存在未經授權的訪問嘗試
  10. 保持更新 —— 定期運行 hermes update 以獲取安全補丁

API 密鑰的安全防護

# 對 `.env` 文件設置適當的權限
chmod 600 ~/.hermes/.env

# 為不同的服務保留單獨的密鑰
# 切勿將 `.env` 文件提交到版本控制

網絡隔離

為實現最大安全性,建議將網關部署在獨立的機器或虛擬機上:

terminal:
backend: ssh
ssh_host: "agent-worker.local"
ssh_user: "hermes"
ssh_key: "~/.ssh/hermes_agent_key"

這可確保網關的消息連接與 Agent 的命令執行相互隔離。