第 10 期 | Hermes Agent 的安全模型与权限控制

更新于 2026/4/15

好的,这是为 Hermes Agent 教程撰写的第 10 期文章。


副标题:理解信任边界、执行前确认机制、沙箱隔离策略,在开放能力与安全防护之间取得平衡。

学习目标

在本期课程中,你将深入探索 Hermes Agent 的安全核心。完成本章学习后,你将能够:

  • 理解 Agent 安全的必要性:认识到赋予 Agent 执行能力的双刃剑效应,并理解为何安全是首要议题。
  • 掌握核心安全概念:清晰地定义并解释信任边界 (Trust Boundary)、执行前确认 (Pre-execution Confirmation) 和沙箱隔离 (Sandbox Isolation) 在 Agent 架构中的作用。
  • 配置安全策略:学会通过修改 Hermes Agent 的配置文件,启用或禁用关键安全特性,并根据实际需求进行调整。
  • 实践沙箱环境搭建:了解如何使用 Docker 为 Agent 的代码执行创建一个隔离、受控的沙箱环境,遵循权限最小化原则 (Principle of Least Privilege)。
  • 做出明智的权衡:在 Agent 的自主性、能力开放性与系统安全性之间,做出合理的决策与平衡。

核心概念讲解

随着我们在前几期课程中不断解锁 Hermes Agent 的强大能力——从调用外部工具 (Skills) 到拥有长期记忆 (Memory),一个至关重要的问题浮出水面:我们如何确保这个日益强大的 AI 实体是安全、可控且值得信赖的?

当一个 Agent 能够生成代码、执行系统命令、访问文件系统、调用外部 API 时,它就不再仅仅是一个聊天机器人。它变成了一个具备潜在行动能力的执行者。这种能力带来了巨大的效率提升,但也引入了同等级别的风险。一个无意的错误指令,或是一次恶意的提示注入 (Prompt Injection),都可能导致数据泄露、系统损坏甚至更严重的后果。

Hermes Agent 的设计哲学是在提供强大功能的同时,内置一个分层、可配置的安全模型。这个模型主要由以下几个核心概念构成。

1. 信任边界 (Trust Boundary)

信任边界是一个理论上的分界线,用于区分系统中可信和不可信的组件。在 Hermes Agent 的世界里,这个边界至关重要。

  • 边界之内 (Trusted)

    • Hermes Agent 核心框架:我们编写和部署的 Agent 主程序代码是可信的。
    • 配置文件:由我们自己定义的 config.ymlskills.yml 等是可信的。
    • 系统环境:运行 Agent 的服务器或本地机器是可信的。
  • 边界之外 (Untrusted)

    • 大型语言模型 (LLM) 的输出:这是最关键的不可信来源。LLM 生成的任何内容,无论是自然语言的思考链 (Chain of Thought),还是准备执行的代码片段 (如 Python, Shell),都绝对不能被无条件信任。它可能会产生有 Bug 的、低效的,甚至是恶意的代码。
    • 用户输入 (User Input):用户的提示可能包含无意的错误,也可能包含恶意的指令,试图绕过安全限制(即 Prompt Injection 攻击)。
    • 外部工具/API 的返回值:Agent 调用的外部 API 或工具返回的数据也应被视为不可信,需要进行适当的验证和清理。

Hermes Agent 的所有安全机制,都建立在“绝不盲目信任边界之外的任何输入”这一基本原则之上。

2. 执行前确认 (Pre-execution Confirmation)

这是第一道,也是最直观的一道防线。它是一种“人类在环”(Human-in-the-Loop) 的安全机制。

当 Agent 的规划器 (Planner) 决定需要执行一个具有潜在副作用的动作时(例如,执行一段代码、调用一个会修改数据的 API、执行一条 Shell 命令),它不会立即执行。相反,它会将完整的执行计划和将要执行的具体代码/命令呈现给用户,并暂停等待用户的明确授权。

工作流程如下:

  1. Agent 接收任务,进行思考和规划。
  2. Agent 生成一个或多个具体的操作步骤,例如一段 Python 代码。
  3. 在执行这段代码之前,Agent 在控制台或消息网关中输出:
    • 意图 (Intent): "我将要下载网页内容并分析标题。"
    • 代码/命令 (Code/Command): requests.get('...'), os.makedirs(...) 等。
    • 确认提示 (Confirmation Prompt): [y/n]
  4. 只有当用户输入 y (yes) 并回车后,Agent 才会继续执行。如果用户输入 n (no) 或其他任何内容,操作将被中止。

这个机制简单而极其有效,它将最终的执行权交还给了人类监督者,防止了 Agent 的“自主失控”,尤其是在开发和调试阶段。

3. 沙箱隔离 (Sandbox Isolation)

如果说“执行前确认”是策略层面的防护,那么“沙箱隔离”就是技术层面的硬隔离。即使我们同意执行一段代码,我们也不希望它能在我们的主系统上为所欲为。

沙箱是一个受限制的、隔离的运行环境。在沙箱内执行的程序,其能力受到严格的控制。它无法访问沙箱之外的文件系统、网络或进程。这就像在一个带锁的、防弹的房间里测试一个潜在的危险设备。

对于 Hermes Agent 这样需要执行 LLM 生成代码的系统,沙箱是必不可少的。最常用和最强大的沙箱技术之一就是 Docker 容器

使用 Docker 作为沙箱的优势:

  • 文件系统隔离:容器拥有自己独立的文件系统。我们可以精确地控制将主机的哪个目录挂载到容器的哪个位置,防止 Agent 访问或修改主机上的敏感文件(如 /etc/passwd, ~/.ssh)。
  • 网络隔离:可以为容器配置独立的网络模式。例如,完全禁止网络访问,或者只允许访问特定的 IP 和端口,有效防止代码向外泄露数据或从未知来源下载恶意软件。
  • 进程隔离:容器内的进程与主机进程隔离,无法干扰或嗅探主机上的其他应用程序。
  • 资源限制:可以限制容器能使用的 CPU 和内存量,防止“代码炸弹”(Code Bomb) 耗尽主机资源。
  • 环境一致性:为 Agent 的代码执行提供一个干净、可复现、包含所有必要依赖(如 requests, pandas)的运行环境。

通过将所有代码执行任务都委托给一个临时的、用完即弃的 Docker 容器,我们极大地降低了潜在风险。即使 LLM 生成了 rm -rf / 这样的恶意代码,并且用户不小心确认了,它也只会删除容器内的根目录,而不会对主机系统造成任何伤害。

4. 权限最小化原则 (Principle of Least Privilege - POLP)

这是一个贯穿所有安全设计的黄金法则。它要求任何组件(无论是 Agent 本身,还是其执行代码的沙箱)只应被授予完成其任务所必需的最小权限。

  • 对于 Agent 进程:如果 Agent 不需要写文件,就不要以可写权限运行它。
  • 对于 API 密钥:提供给 Agent 的云服务(如 AWS, GCP)API Key,应该使用 IAM (Identity and Access Management) 等工具创建具有严格范围限制的密钥,而不是使用拥有完全权限的根密钥。
  • 对于沙箱容器
    • 非 Root 用户:在 Dockerfile 中,应创建一个非 root 用户,并使用 USER 指令切换到该用户。这可以防止容器内的进程拥有过高的权限。
    • 精确挂载:只挂载一个专门的工作目录(如 ./workspace),而不是整个项目目录或用户主目录。
    • 受限网络:如果任务不需要访问互联网,就使用 --network=none 来运行容器。

将这四大概念结合起来,Hermes Agent 构建了一个纵深防御体系:在清晰的信任边界之上,通过执行前确认进行决策把关,再利用沙大箱隔离技术限制破坏半径,并始终遵循权限最小化原则来收紧所有环节的权限。

💻 实战演示

接下来,我们将通过修改 Hermes Agent 的配置文件,亲身体验这些安全机制如何工作。

假设我们的任务是:“请帮我获取 Hermes Agent 在 GitHub 上的 README.md 文件的内容,并统计其中有多少个 'Agent' 单词,最后将结果保存到 analysis_result.txt 文件中。

这个任务涉及:

  1. 网络请求 (访问 GitHub)
  2. 文件系统写入 (保存结果)

这是一个典型的需要安全审查的操作。

场景 1: 完全开放模式(危险!仅供演示)

首先,我们模拟一个完全信任 Agent 的、极不安全的配置。

  1. 修改配置文件 打开 config/config.yml,找到 security 部分(如果不存在,请自行添加),并进行如下配置:

    # config/config.yml
    
    # ... other configurations ...
    
    security:
      # 是否在执行代码或命令前需要用户确认
      require_confirmation: false
      # 执行环境配置
      execution_environment:
        # 'local' 表示直接在主机上执行,非常危险!
        type: "local"
    
  2. 启动 Agent 并下达指令

    ./hermes-agent run
    

    在 Agent 的交互界面中输入我们的任务:

    User: 请帮我获取 Hermes Agent 在 GitHub 上的 README.md 文件的内容,并统计其中有多少个 'Agent' 单词,最后将结果保存到 analysis_result.txt 文件中。

  3. 观察行为 你会看到 Agent 思考后,不经任何询问,直接开始执行。它的日志中可能会显示类似以下的输出:

    [INFO] Planner: I need to use Python to perform this task. I will fetch the URL, count the word, and write to a file.
    [INFO] Executor: Executing the following code directly on the local machine:
    
    import requests
    
    url = "https://raw.githubusercontent.com/hermes-project/hermes-agent/main/README.md"
    try:
        response = requests.get(url)
        response.raise_for_status()
        content = response.text
        count = content.lower().count('agent')
        result_message = f"The word 'Agent' appears {count} times."
        
        with open("analysis_result.txt", "w") as f:
            f.write(result_message)
            
        print(result_message)
        print("Result saved to analysis_result.txt")
        
    except requests.exceptions.RequestException as e:
        print(f"Error fetching URL: {e}")
    
    [INFO] Execution finished.
    The word 'Agent' appears 12 times.
    Result saved to analysis_result.txt
    

    此时,项目根目录下会凭空出现一个 analysis_result.txt 文件。这个过程非常顺滑,但也极其危险。如果 LLM 生成的代码是 import os; os.system('rm -rf ~'),你的用户主目录可能就遭殃了。

场景 2: 启用执行前确认(推荐的基本安全配置)

现在,我们开启第一道防线。

  1. 修改配置文件require_confirmation 改为 true

    # config/config.yml
    security:
      require_confirmation: true # <--- 改为 true
      execution_environment:
        type: "local"
    
  2. 再次执行任务 重启 Agent,输入相同的指令。

  3. 观察行为 这次,Agent 的行为完全不同。在生成代码后,它会停下来等待你的许可:

    [INFO] Planner: I need to use Python to perform this task. I will fetch the URL, count the word, and write to a file.
    
    [CONFIRMATION REQUIRED] The agent plans to execute the following Python code.
    Please review it carefully.
    
    Actions to be taken:
    - Make a network request to https://raw.githubusercontent.com
    - Write to the local file: analysis_result.txt
    
    Code:
    ----------------------------------------------------------------------
    import requests
    
    url = "https://raw.githubusercontent.com/hermes-project/hermes-agent/main/README.md"
    try:
        response = requests.get(url)
        response.raise_for_status()
        content = response.text
        count = content.lower().count('agent')
        result_message = f"The word 'Agent' appears {count} times."
        
        with open("analysis_result.txt", "w") as f:
            f.write(result_message)
            
        print(result_message)
        print("Result saved to analysis_result.txt")
        
    except requests.exceptions.RequestException as e:
        print(f"Error fetching URL: {e}")
    ----------------------------------------------------------------------
    
    Do you approve this action? [y/n]: 
    

    现在,你有机会审查代码。你看到它确实是在执行你要求的任务,没有恶意行为。于是你输入 y 并回车,Agent 才会继续执行,并最终完成任务。如果你输入 n,它会中止操作并告知你用户拒绝了执行。

场景 3: 启用 Docker 沙箱隔离(最高安全级别)

最后,我们启用终极防护:Docker 沙箱。

  1. 准备 Docker 环境 首先,确保你已经安装了 Docker。然后,我们需要创建一个用于代码执行的 Docker 镜像。

    在你的项目根目录下,创建一个名为 sandbox 的文件夹,并在其中创建一个 Dockerfile 文件:

    mkdir sandbox
    cd sandbox
    touch Dockerfile
    

    编辑 Dockerfile 内容如下:

    # Dockerfile
    
    # 使用一个轻量的 Python 镜像作为基础
    FROM python:3.10-slim
    
    # 安装必要的库,例如我们的任务需要 requests
    RUN pip install requests
    
    # --- 权限最小化原则实践 ---
    # 创建一个工作目录
    WORKDIR /app/workspace
    
    # 创建一个没有特权的普通用户 hermesuser
    RUN useradd -m -d /app hermesuser
    
    # 切换到这个非 root 用户
    USER hermesuser
    
    # 默认情况下,容器启动后不做任何事,等待 Agent 传入命令
    CMD ["/bin/bash"]
    
  2. 构建 Docker 镜像sandbox 目录下,执行构建命令:

    # 在 sandbox 文件夹内执行
    docker build -t hermes/python-sandbox:latest .
    

    这会创建一个名为 hermes/python-sandbox 的镜像,我们将在配置中引用它。

  3. 修改配置文件 现在,我们来配置 Hermes Agent,让它使用这个 Docker 沙箱。

    # config/config.yml
    security:
      require_confirmation: true
      execution_environment:
        type: "docker" # <--- 改为 docker
        docker:
          # 我们刚刚构建的镜像
          image: "hermes/python-sandbox:latest"
          
          # 容器内的工作目录
          working_dir: "/app/workspace"
          
          # 将主机的 ./workspace 目录挂载到容器的工作目录
          # 这允许 Agent 与主机交换文件,但仅限于这个受控的目录
          volume_mounts:
            - type: bind
              source: "./workspace" # 主机上的相对路径
              target: "/app/workspace" # 容器内的绝对路径
              
          # 网络模式。'bridge' 是默认模式,允许访问外部网络。
          # 如果任务不需要联网,可以设为 'none'。
          network_mode: "bridge"
          
          # 资源限制(可选)
          # mem_limit: "256m"
          # cpus: "0.5"
    

    注意: 你需要在项目根目录下手动创建一个 workspace 文件夹,用于与容器共享文件。

    # 在项目根目录
    mkdir workspace
    
  4. 再次执行任务 重启 Agent,输入相同的指令。

  5. 观察行为 这次,流程如下:

    • Agent 依然会请求你的确认(因为 require_confirmationtrue)。
    • 当你输入 y 之后,日志会显示与之前不同的信息:
    [INFO] User approved the action.
    [INFO] Execution Environment: Docker. Preparing container...
    [INFO] Starting Docker container from image 'hermes/python-sandbox:latest'.
    [INFO] Mounting local './workspace' to '/app/workspace' in container.
    [INFO] Executing code inside the Docker sandbox...
    
    [DOCKER_STDOUT] The word 'Agent' appears 12 times.
    [DOCKER_STDOUT] Result saved to analysis_result.txt
    
    [INFO] Execution finished. Container stopped and removed.
    

    现在,analysis_result.txt 文件会出现在你主机的 ./workspace 目录下,而不是项目根目录。

    我们成功地将代码执行限制在了 Docker 容器内。代码对文件系统的写操作被重定向到了受控的 workspace 目录。它在容器内以非 root 用户 hermesuser 运行。即使这段代码有漏洞或恶意行为,它能造成的破坏也被牢牢地限制在了这个临时的、隔离的容器之内。

涉及命令

  • mkdir sandbox workspace: 创建沙箱配置和工作区目录。
  • touch sandbox/Dockerfile: 创建 Dockerfile 文件。
  • docker build -t hermes/python-sandbox:latest .: 构建用于沙箱的 Docker 镜像。
  • vim config/config.yml: (或使用你喜欢的编辑器) 修改 Agent 的安全配置。
  • ./hermes-agent run: 启动 Hermes Agent。

要点回顾

  • 安全不是可选项:对于能够执行代码的 Agent 来说,安全是设计的基石。
  • 分层防御:Hermes Agent 的安全模型是分层的,包括策略层(确认机制)和技术层(沙箱隔离)。
  • 永不信任 LLM:必须将 LLM 的输出视为不可信的外部输入,进行审查和隔离。
  • 人类在环是关键require_confirmation: true 是最简单有效的安全开关,它确保了最终决策权在你手中。
  • 沙箱是终极保障:使用 Docker 等技术创建沙箱环境,可以从根本上限制潜在恶意代码的破坏范围,是生产环境部署的推荐实践。
  • 权限最小化:无论是 Agent 进程、API 密钥还是沙箱配置,始终遵循权限最小化原则,只授予必要的权限。
  • 安全与便利的权衡local 模式最方便但最危险,docker 模式最安全但配置稍复杂。你需要根据应用场景(开发、个人使用、生产部署)来选择合适的安全级别。

通过本期的学习,你已经掌握了保护 Hermes Agent 的核心知识和技能。在未来的探索中,请始终将安全意识放在首位,负责任地构建和使用强大的 AI Agent。

参考资料