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)