安全架构

📚 学习路径:本文档是架构文档的第 10 部分。建议按顺序阅读:

前言

安全架构是 OpenClaw 的重要组成部分,负责保护系统和用户数据的安全。作为一个高权限系统,OpenClaw 需要特别注意安全。本文档将深入解析安全架构的设计、安全机制和最佳实践。

通过阅读本文档,你将能够:

  • 理解安全架构的设计理念
  • 掌握多层安全防护机制
  • 了解访问控制和权限管理
  • 理解沙箱隔离和执行安全

一、安全架构概述

1.1 为什么需要安全架构?

安全防护

安全风险

数据泄露

未授权访问

恶意执行

资源滥用

访问控制

沙箱隔离

数据加密

审计日志

风险说明防护措施
数据泄露敏感数据被泄露访问控制 + 数据加密
未授权访问未授权用户访问系统访问控制 + 身份验证
恶意执行恶意命令被执行沙箱隔离 + 命令白名单
资源滥用系统资源被滥用沙箱隔离 + 资源限制

1.2 安全架构的目标

实现方式

安全目标

数据保护

访问控制

执行安全

审计追踪

加密存储

身份验证

沙箱隔离

日志记录

目标说明实现方式
数据保护保护敏感数据不被泄露加密存储
访问控制控制谁可以访问系统身份验证 + 权限管理
执行安全安全地执行命令和工具沙箱隔离 + 命令白名单
审计追踪记录所有操作以便审计日志记录

二、多层安全防护

2.1 安全层次

数据层

执行层

访问层

身份层

网络层

默认绑定 127.0.0.1

SSH 隧道或 Tailscale

Token/密码认证

设备配对

白名单机制

DM 配对审批

群聊策略控制

主会话完全信任

私聊/群聊沙箱隔离

命令白名单

上下文隔离

密钥隔离存储

敏感工具沙箱

2.2 网络安全

默认绑定 127.0.0.1

// src/gateway/server.impl.ts
const wsServer = new WebSocket.Server({
  port,
  host: '127.0.0.1',  // 默认只监听本地
});

远程访问

通过 SSH 隧道或 Tailscale:

# SSH 隧道
ssh -L 18789:localhost:18789 user@remote-server

# Tailscale
tailscale up

2.3 身份验证

Token/密码认证

// src/auth/token-auth.ts
export function verifyToken(token: string): boolean {
  const validTokens = loadValidTokens();
  return validTokens.includes(token);
}

设备配对

// src/auth/device-pairing.ts
export interface DevicePairing {
  deviceId: string;
  deviceKey: string;
  pairedAt: Date;
  lastSeen: Date;
}

export function isDevicePaired(deviceId: string): boolean {
  const pairing = loadDevicePairing(deviceId);
  return pairing !== null;
}

2.4 访问控制

白名单机制

代码位置src/channels/allowlist-match.ts

export function isInAllowlist(
  userId: string,
  allowlist: string[],
): boolean {
  return allowlist.includes(userId);
}

私聊策略

export type DMPolicy = 'pairing' | 'open' | 'disabled';

export function checkDMPolicy(
  userId: string,
  policy: DMPolicy,
): boolean {
  switch (policy) {
    case 'pairing':
      return isDevicePaired(userId);
    case 'open':
      return true;
    case 'disabled':
      return false;
  }
}

群聊策略

export type GroupPolicy = 'always' | 'mention_only' | 'disabled';

export function checkGroupPolicy(
  message: InboundMessage,
  policy: GroupPolicy,
): boolean {
  switch (policy) {
    case 'always':
      return true;
    case 'mention_only':
      return isMentioned(message);
    case 'disabled':
      return false;
  }
}

三、沙箱隔离

3.1 沙箱级别

网络访问

工具权限

隔离程度

沙箱级别

主会话

私聊会话

群组会话

线程会话

完全信任

沙箱隔离

沙箱隔离

沙箱隔离

所有工具

限制工具

限制工具

限制工具

允许

禁止

禁止

禁止

会话类型沙箱级别允许的工具网络访问
主会话完全信任所有工具允许
私聊会话沙箱隔离限制工具禁止
群组会话沙箱隔离限制工具禁止
线程会话沙箱隔离限制工具禁止

3.2 沙箱实现

代码位置src/agents/sandbox.ts

export class Sandbox {
  constructor(private config: SandboxConfig) {
    // 初始化沙箱环境
  }

  async exec(command: string, args: string[]): Promise<ExecResult> {
    // 1. 验证命令安全性
    if (!this.isCommandSafe(command)) {
      throw new Error('Command not allowed');
    }

    // 2. 限制资源使用
    const limits = this.config.limits;
    const options = {
      timeout: limits.timeout,
      maxMemory: limits.maxMemory,
    };

    // 3. 执行命令
    const result = await this.runCommand(command, args, options);

    return result;
  }

  private isCommandSafe(command: string): boolean {
    // 检查命令是否在白名单中
    return ALLOWED_COMMANDS.includes(command);
  }
}

3.3 命令白名单

const ALLOWED_COMMANDS = [
  'ls',
  'cat',
  'grep',
  'find',
  'echo',
  'pwd',
  'date',
  'whoami',
  // ... 更多安全命令
];

export function isCommandSafe(command: string): boolean {
  return ALLOWED_COMMANDS.includes(command);
}

3.4 资源限制

export interface SandboxLimits {
  timeout: number;      // 超时时间(毫秒)
  maxMemory: number;    // 最大内存(字节)
  maxCpu: number;       // 最大 CPU 使用率(百分比)
  maxProcesses: number; // 最大进程数
}

const DEFAULT_LIMITS: SandboxLimits = {
  timeout: 30000,       // 30 秒
  maxMemory: 512 * 1024 * 1024,  // 512 MB
  maxCpu: 50,           // 50%
  maxProcesses: 10,     // 10 个进程
};

四、数据安全

4.1 数据加密

敏感数据加密

// src/security/encryption.ts
import crypto from 'crypto';

export function encrypt(data: string, key: string): string {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  let encrypted = cipher.update(data, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return iv.toString('hex') + ':' + encrypted;
}

export function decrypt(encrypted: string, key: string): string {
  const parts = encrypted.split(':');
  const iv = Buffer.from(parts[0], 'hex');
  const encryptedData = parts[1];
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

4.2 凭据管理

凭据存储

~/.openclaw/credentials/
├── openai.json
├── anthropic.json
└── custom.json

权限设置

chmod 600 ~/.openclaw/credentials/*

代码实现

// src/security/credentials.ts
export async function loadCredentials(
  provider: string,
): Promise<Credentials> {
  const credPath = resolveCredentialsPath(provider);

  // 检查文件权限
  const stats = await fs.stat(credPath);
  const mode = stats.mode & 0o777;
  if (mode !== 0o600) {
    throw new Error('Credentials file must have 0600 permissions');
  }

  // 读取凭据
  const content = await fs.readFile(credPath, 'utf-8');
  return JSON.parse(content);
}

4.3 上下文隔离

会话隔离

// 不同会话使用不同的上下文
export function isolateSessionContext(
  sessionKey: string,
): SessionContext {
  return {
    sessionKey,
    messages: [],
    tools: [],
    memories: [],
  };
}

密钥隔离

// 不同会话使用不同的密钥
export function getSessionKey(
  sessionKey: string,
): string {
  const baseKey = loadBaseKey();
  return crypto
    .createHash('sha256')
    .update(baseKey + sessionKey)
    .digest('hex');
}

五、提示词注入防御

5.1 上下文隔离

// 防止用户消息影响系统提示词
export function buildPrompt(
  systemPrompt: string,
  userMessage: string,
): string {
  return `
${systemPrompt}

---
User Message:
${userMessage}
  `.trim();
}

5.2 敏感工具沙箱

// 敏感工具在沙箱中执行
export async function executeSensitiveTool(
  toolCall: ToolCall,
): Promise<ToolResult> {
  const sandbox = new Sandbox({
    limits: SENSITIVE_TOOL_LIMITS,
  });

  return sandbox.exec(toolCall.command, toolCall.args);
}

5.3 密钥隔离存储

// 密钥与用户消息隔离
export async function loadApiKey(
  provider: string,
): Promise<string> {
  const credentials = await loadCredentials(provider);
  return credentials.apiKey;
}

六、审计日志

6.1 日志记录

代码位置src/security/audit-log.ts

export interface AuditLogEntry {
  timestamp: Date;
  userId: string;
  action: string;
  resource: string;
  result: 'success' | 'failure';
  details?: Record<string, unknown>;
}

export async function logAuditEvent(
  entry: AuditLogEntry,
): Promise<void> {
  const logPath = resolveAuditLogPath();
  const line = JSON.stringify(entry) + '\n';
  await fs.appendFile(logPath, line, 'utf-8');
}

6.2 日志查询

export async function queryAuditLogs(
  filters: AuditLogFilters,
): Promise<AuditLogEntry[]> {
  const logPath = resolveAuditLogPath();
  const lines = await fs.readFile(logPath, 'utf-8');
  const entries = lines
    .split('\n')
    .filter(line => line.trim())
    .map(line => JSON.parse(line) as AuditLogEntry);

  // 应用过滤条件
  let filtered = entries;

  if (filters.userId) {
    filtered = filtered.filter(e => e.userId === filters.userId);
  }

  if (filters.action) {
    filtered = filtered.filter(e => e.action === filters.action);
  }

  if (filters.startTime) {
    filtered = filtered.filter(e => e.timestamp >= filters.startTime);
  }

  if (filters.endTime) {
    filtered = filtered.filter(e => e.timestamp <= filters.endTime);
  }

  return filtered;
}

6.3 日志分析

export async function analyzeAuditLogs(
  period: DateRange,
): Promise<AuditLogAnalysis> {
  const logs = await queryAuditLogs({
    startTime: period.start,
    endTime: period.end,
  });

  return {
    totalEvents: logs.length,
    successRate: logs.filter(l => l.result === 'success').length / logs.length,
    topActions: getTopActions(logs),
    topUsers: getTopUsers(logs),
    failedEvents: logs.filter(l => l.result === 'failure'),
  };
}

七、安全最佳实践

7.1 网络安全

  • ✅ 默认绑定 127.0.0.1,不暴露到公网
  • ✅ 使用 SSH 隧道或 Tailscale 进行远程访问
  • ✅ 定期更新依赖库,修复安全漏洞
  • ✅ 使用 HTTPS/TLS 加密通信

7.2 访问控制

  • ✅ 启用白名单机制,限制访问用户
  • ✅ 使用强密码或 Token 进行身份验证
  • ✅ 定期轮换 API Key 和密码
  • ✅ 实施最小权限原则

7.3 执行安全

  • ✅ 使用沙箱隔离执行命令
  • ✅ 实施命令白名单机制
  • ✅ 限制资源使用(CPU、内存、超时)
  • ✅ 禁止网络访问(主会话除外)

7.4 数据安全

  • ✅ 加密存储敏感数据
  • ✅ 设置正确的文件权限(0600)
  • ✅ 定期备份重要数据
  • ✅ 实施数据隔离策略

7.5 审计和监控

  • ✅ 记录所有重要操作
  • ✅ 定期审计日志,发现异常行为
  • ✅ 监控系统资源使用情况
  • ✅ 设置告警机制,及时发现安全问题

八、核心代码文件索引

文件路径功能重要性
src/security/encryption.ts加密解密⭐⭐⭐⭐
src/security/credentials.ts凭据管理⭐⭐⭐⭐⭐
src/security/audit-log.ts审计日志⭐⭐⭐⭐
src/agents/sandbox.ts沙箱隔离⭐⭐⭐⭐⭐
src/channels/allowlist-match.ts白名单匹配⭐⭐⭐⭐
src/auth/token-auth.tsToken 认证⭐⭐⭐⭐
src/auth/device-pairing.ts设备配对⭐⭐⭐

九、下一步

恭喜你完成了安全架构的学习!接下来建议:


通过理解安全架构的工作原理,你已经掌握了 OpenClaw 的安全机制!


总结

恭喜你完成了 OpenClaw 架构文档的全部学习!你已经掌握了:

  1. 技术基础:TypeScript 技术特性
  2. 整体框架:OpenClaw 架构设计
  3. 消息流转:消息的完整生命周期
  4. 设计原理:反共识设计思想
  5. Gateway:控制平面深度解析
  6. Agent:运行机制和工具执行
  7. 会话管理:会话生命周期和隔离
  8. 记忆系统:长期记忆和混合检索
  9. 并发控制:队列系统和调度策略
  10. 安全架构:多层安全防护机制
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐