1
0
0

沙箱与安全机制

2026-08-14
2026-08-14
沙箱与安全机制
文章摘要
|
# 入门07:沙箱与安全机制 > AI Agent 能执行代码、操作文件、访问网络——这些能力很强大,但如果不受控制,可能搞出乱子。Harness 提供了多层安全保护,就像给 AI 套上了"安全绳"。 --- ## 1. 安全架构总览 ```mermaid graph TB subgraph "安全分层" L1[L1: 沙箱隔离 - 像 iframe sandbox] L2[L2: 凭证管理 - 像 .env 文件] L3[L3: 环境清洗 - 擦除敏感环境变量] L4[L4: 超时控制 - 像 Promise.race] L5[L5: 工具守卫 - 限制工具使用] L6[L6: 用户审批 - 敏感操作需确认] end subgraph "Agent 执行路径" CMD[命令执行] --> L1 CMD --> L3 FS[文件操作] --> L1 FS --> L2 WEB[网络访问] --> L4 WEB --> L6 ALL[所有工具调用] --> L5 end ``` --- ## 2. 沙箱系统 — 像 iframe 的 sandbox 属性 **解决的问题**:让 AI 在"笼子"里执行代码,关起来、跑不了、搞不坏。 **代码位置**:`packages/sandbox/sandbox/src/index.ts` ```typescript abstract class Sandbox extends Service { abstract exec(command: string, options?: ExecOptions): Promise abstract fs: FileSystem // 沙箱里的文件系统 abstract info: SandboxInfo } ``` ### 三种沙箱实现 | 沙箱 | 用啥技术 | 像什么 | |------|---------|--------| | **本地沙箱** | Linux Landlock / bubblewrap | 给进程画个"圈",只能在圈里活动 | | **E2B 沙箱** | 远程容器 | 在云上的 Docker 容器里跑 | | **Windows ACL** | Windows 权限控制 | 用 Windows 文件权限限制 | ### 沙箱策略 ```typescript interface SandboxPolicy { allowedPaths: string[] // 允许访问的路径(白名单) deniedPaths: string[] // 禁止访问的路径(黑名单) networkAccess: 'allowed' | 'denied' | 'restricted' // 网络权限 maxMemory?: number // 最大内存 maxCpuTime?: number // 最长 CPU 时间 maxDiskSpace?: number // 最大磁盘空间 } ``` --- ## 3. 凭证管理 — 像 `.env` 文件 **解决的问题**:API 密钥、密码等敏感信息不能硬编码,要安全地存、安全地取。 **代码位置**:`packages/credentials/credentials/src/index.ts` ```mermaid graph TB subgraph "凭证来源(就像 .env 文件)" ENV[环境变量] FILE[凭证文件] USER[用户输入] end subgraph "凭证服务" CR[CredentialProvider] RES[解析 - 按需获取] SET[设置凭证] UNSET[删除凭证] end subgraph "谁在用" LLM[LLM 适配器 - 需要 API Key] SVC[其他服务] end ENV --> CR FILE --> CR USER --> CR CR --> RES RES --> LLM RES --> SVC ``` ```typescript abstract class CredentialProvider extends Service { // 解析凭证(比如从环境变量读 API Key) abstract resolve(ref: string): Promise abstract set(ref: string, value: CredentialValue): Promise abstract unset(ref: string): Promise } ``` **凭证格式**:用 POSIX 风格的路径引用,比如 `credentialRef('api/deepseek/primary')` --- ## 4. 环境变量清洗 **解决的问题**:创建子进程时,自动清除可能泄露的敏感信息。 **代码位置**:`packages/subprocess/subprocess/src/index.ts` ```typescript abstract class SubprocessRuntime extends Service { // 清洗父进程的环境变量 scrubbedParentEnv(): Record { const env = { ...process.env } // 删掉所有含 KEY/SECRET/TOKEN 等敏感词的环境变量 for (const key of Object.keys(env)) { if (SENSITIVE_ENV_PATTERN.test(key)) { delete env[key] } } // 删掉 DSH_ 开头的内部变量 for (const key of Object.keys(env)) { if (key.startsWith('DSH_')) { delete env[key] } } return env } } // 匹配模式:KEY, SECRET, TOKEN, PASSWORD, CREDENTIAL 等 const SENSITIVE_ENV_PATTERN = /(KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL)/i ``` --- ## 5. 超时控制 — 就像 Promise.race 加个超时 **解决的问题**:防止 AI 或工具执行时间过长,把系统资源耗尽。 **代码位置**:`packages/guard/timeout-policy/src/index.ts` ```typescript class TimeoutPolicy extends Service { // 拦截工具执行,设置超时 ctx.waterfall('tools/execute', (execution) => { const deadline = this.deadline(execution.definition.timeoutMs) return withTimeout(execution, deadline) }) } // 超时了咋办? const TOOL_TIMEOUT = { success: false, error: { type: 'TOOL_TIMEOUT', message: '执行超时了,请简化操作', }, } ``` **可配置的超时**: ```yaml plugins: - name: timeout-policy config: toolTimeout: 300_000 # 工具执行超时 5 分钟 turnTimeout: 600_000 # 单个回合超时 10 分钟 llmTimeout: 120_000 # AI 调用超时 2 分钟 ``` --- ## 6. 重复工具调用守卫 **解决的问题**:AI 有时候会蠢到反复调用同一个工具(比如陷入死循环)。 **代码位置**:`packages/guard/repeat-tool-reminder/src/index.ts` ```typescript class RepeatToolReminder extends Service { ctx.waterfall('tools/create', (execution) => { const recentCalls = this.getRecentCalls(execution.name, 5) if (recentCalls >= 3) { execution.reminder = 'gentle' // "你刚才已经调过 3 次了" } if (recentCalls >= 5) { execution.reminder = 'detailed' // 详细提醒 } if (recentCalls >= 8) { execution.reminder = 'stop' // "建议换个方式" } return execution }) } ``` --- ## 7. 用户审批 **解决的问题**:敏感操作需要用户确认,就像手机 App 需要你授权才能发短信。 **代码位置**:`packages/interaction/user-approval/src/index.ts` ```typescript class UserApprovalService extends Service { async requestApproval(context: ApprovalContext): Promise { // 向用户弹窗:"AI 要执行 xxx 操作,是否允许?" return { approved: true, // 用户点了"允许" timestamp: Date.now(), note: '用户确认了', } } } ``` --- ## 8. 安全配置示例 在 `cordis.yml` 里配置安全策略: ```yaml plugins: # 沙箱配置 - name: sandbox path: @deepseek-ai/dsh-sandbox-local config: policy: allowedPaths: # AI 只能访问这些目录 - /home/user/project - /tmp deniedPaths: # 这些目录不能碰 - /etc - /usr networkAccess: allowed # 超时策略 - name: timeout-policy config: toolTimeout: 300_000 turnTimeout: 600_000 # 权限预设 - name: permission-presets config: presets: - name: safe allowList: ['read', 'glob', 'grep', 'web_search'] # 只读模式 - name: developer allowList: ['read', 'write', 'bash', 'web_search'] # 开发模式 ``` --- ## 要点总结 - **沙箱** = 像 iframe sandbox,把 AI 关在"笼子"里执行代码 - **凭证管理** = 像 `.env` 文件,安全地存 API Key - **环境清洗** = 子进程启动前自动擦除敏感环境变量 - **超时控制** = 像 Promise.race 加超时,防止死循环 - **重复守卫** = 检测 AI 反复调同一个工具,给出提醒 - **用户审批** = 敏感操作需要用户确认 ## 进阶阅读 - 沙箱源码:`packages/sandbox/sandbox/src/` - 凭证管理:`packages/credentials/credentials/src/` - 超时守卫:`packages/guard/timeout-policy/src/` - 名词速查:[附录-AI 概念名词速查手册](附录-AI概念名词速查手册.md) - 下一步:[08-宿主层与 SDK API](08-宿主层与SDKAPI.md)

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!