首页 › tutorials › Claude Code权限与安全沙箱全实战

Claude Code 权限体系与安全沙箱全实战:从权限配置到Docker隔离的完整防护指南

概述

本教程面向需要在团队或生产环境中安全使用 Claude Code 的开发者和安全工程师。你将学会:配置 settings.json 的 allow/deny 权限规则、使用 Hooks 拦截危险操作、搭建 Docker 沙箱实现文件系统与网络隔离,最终构建一套多层防御的 Claude Code 安全体系。适合有一定 Claude Code 使用基础、关注安全合规的技术人员。

适用人群:中高级开发者、DevOps 工程师、安全工程师、技术团队负责人
预计学习时长:3-4 小时(含动手实践)


前置条件

要求 说明
Claude Code CLI 已安装并完成基本配置(npm install -g @anthropic-ai/claude-code)
Node.js 18+ Claude Code 运行环境
Docker(可选) 第四章沙箱实践需要
Linux/macOS 本教程命令以 Linux/macOS 为主
基础 CLI 能力 熟悉终端操作和 JSON 编辑

第一章:Claude Code 权限模型深度解析

1.1 三级权限控制:Ask / Allow / Deny

Claude Code 的每一次工具调用(Tool Call)——无论是执行 Bash 命令、编辑文件,还是发起网络请求——都必须经过权限系统的审核。这个系统基于三条核心规则运作:

┌─────────────────────────────────────────────────┐
│              Claude Code 权限决策树               │
├─────────────────────────────────────────────────┤
│                                                 │
│  工具调用请求                                     │
│       │                                         │
│       ▼                                         │
│  ┌─────────┐   匹配   ┌──────────────────┐      │
│  │ Deny 规则├────────►│ ❌ 直接拒绝(静默)│      │
│  └────┬────┘          └──────────────────┘      │
│       │ 不匹配                                    │
│       ▼                                           │
│  ┌──────────┐  匹配  ┌───────────────────┐       │
│  │ Allow 规则├───────►│ ✅ 自动放行(无提示)│      │
│  └────┬─────┘        └───────────────────┘       │
│       │ 不匹配                                     │
│       ▼                                            │
│  ┌──────────────────────────────┐                 │
│  │ 🟡 弹出确认对话框(Ask 模式)│                 │
│  │ 用户手动选择 Allow / Deny    │                 │
│  └──────────────────────────────┘                 │
│                                                   │
└─────────────────────────────────────────────────┘

关键原则:Deny 优先于 Allow。 如果一条规则同时匹配 deny 和 allow,deny 始终获胜。这确保了安全策略的绝对权威。

1.2 权限配置的层级结构

Claude Code 的配置文件分布在三个层级,形成一套继承与覆盖的体系:

~/.claude/settings.json              ← 全局配置(对所有项目生效)
  └── 项目根目录/.claude/settings.json   ← 项目配置(仅对当前项目生效)
       └── settings.local.json          ← 本地配置(不提交到 Git)

优先级规则: - deny 规则:全局 deny + 项目 deny 取并集,全部生效 - allow 规则:项目级 allow 覆盖全局级 allow - settings.local.json:覆盖同目录下的 settings.json(用于个人偏好,不进版本控制)

1.3 settings.json 完整结构

{
  "permissions": {
    "allow": [
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(npm test *)",
      "Bash(npm run lint *)",
      "Read",
      "Glob",
      "Grep"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(curl * | bash *)",
      "Bash(sudo *)",
      "Bash(chmod 777 *)",
      "Edit(*.env*)",
      "Write(*.env*)",
      "Write(*secret*)",
      "Write(*credential*)"
    ]
  }
}

语法解析:

模式 含义 示例
"Tool" 允许该工具的所有调用 "Read" → 可读任意文件
"Tool(prefix)" 匹配以 prefix 开头的参数 "Bash(git *)" → 允许所有 git 命令
"Tool(*keyword*)" 参数包含 keyword "Bash(*npm test*)"
"Tool(path/*)" 路径 glob 匹配 "Edit(src/**)" → 只允许编辑 src 目录

1.4 各工具的权限语法详解

Bash 工具

Bash 是最需要严格控制的工具,因为它能执行任意系统命令:

{
  "permissions": {
    "allow": [
      "Bash(git *)",
      "Bash(npm *)",
      "Bash(npx *)",
      "Bash(node *)",
      "Bash(python *)",
      "Bash(ls *)",
      "Bash(cat *)",
      "Bash(echo *)",
      "Bash(mkdir *)",
      "Bash(cp *)",
      "Bash(mv *)"
    ],
    "deny": [
      "Bash(rm -rf /)",
      "Bash(rm -rf ~*)",
      "Bash(sudo *)",
      "Bash(su *)",
      "Bash(chmod 777 *)",
      "Bash(curl * | sh)",
      "Bash(curl * | bash)",
      "Bash(wget * | sh)",
      "Bash(aws s3 rm *)",
      "Bash(docker rm *)",
      "Bash(kubectl delete *)",
      "Bash(pkill *)",
      "Bash(kill -9 *)"
    ]
  }
}

文件操作工具(Read / Edit / Write)

{
  "permissions": {
    "allow": [
      "Read",
      "Edit(src/**)",
      "Edit(tests/**)",
      "Write(src/**)",
      "Write(tests/**)"
    ],
    "deny": [
      "Edit(.env*)",
      "Edit(*.pem)",
      "Edit(*.key)",
      "Write(.env*)",
      "Write(*.pem)",
      "Write(*.key)",
      "Write(/etc/*)",
      "Write(/var/*)",
      "Edit(package.json)",
      "Edit(package-lock.json)"
    ]
  }
}

网络工具(WebFetch / WebSearch)

{
  "permissions": {
    "allow": [
      "WebFetch",
      "WebSearch"
    ],
    "deny": [
      "WebFetch(http://localhost*)",
      "WebFetch(http://127.0.0.1*)",
      "WebFetch(http://192.168.*)",
      "WebFetch(http://10.*)",
      "WebFetch(http://172.16.*)"
    ]
  }
}

为什么禁止访问内网地址? 在 CI/CD 或共享环境中,Claude Code 可能通过 WebFetch 发起 SSRF(Server-Side Request Forgery)攻击,访问内部服务。

1.5 通过 CLI 快速配置权限

除了手动编辑 JSON,Claude Code 提供了交互式权限管理:

# 启动时预设权限
claude --allow "Bash(git *)" --allow "Bash(npm test *)" --deny "Bash(sudo *)"

# 在会话中管理权限
/permissions          # 打开权限管理面板
/permissions allow    # 查看所有 allow 规则
/permissions deny     # 查看所有 deny 规则

常见问题与解决:

问题 原因 解决方案
规则不生效 JSON 语法错误 用 jq . ~/.claude/settings.json 验证
allow 了还是弹窗 deny 规则也匹配了 检查是否有冲突的 deny 规则
路径匹配不到 glob 模式不对 使用 src/** 而非 src/* 递归匹配
权限太多太乱 配置文件膨胀 按工具分组,定期清理无用规则

第二章:Hooks——代码级安全守卫

2.1 Hooks 是什么?为什么比权限更强?

settings.json 的 allow/deny 是静态的字符串匹配,能力有限。Hooks 则允许你在工具调用的生命周期中注入任意 Shell 脚本逻辑——你可以检查文件内容、调用外部 API、执行复杂的条件判断,然后决定放行还是拦截。

sequenceDiagram
    participant User as 用户/Claude
    participant HookSystem as Hook 引擎
    participant PreHook as PreToolUse Hook
    participant Tool as 目标工具
    participant PostHook as PostToolUse Hook

    User->>HookSystem: 发起工具调用
    HookSystem->>PreHook: 传递工具名+参数(JSON)
    alt PreHook 返回 exit 0
        PreHook->>HookSystem: 放行
        HookSystem->>Tool: 执行工具
        Tool->>HookSystem: 返回结果
        HookSystem->>PostHook: 传递结果(JSON)
        PostHook->>HookSystem: 后处理完成
        HookSystem->>User: 返回最终结果
    else PreHook 返回 exit 2
        PreHook->>HookSystem: 拦截(反馈给 Claude)
        HookSystem->>User: 返回拦截原因
    else PreHook 返回 exit 1 或超时
        PreHook->>HookSystem: 静默放行
        HookSystem->>Tool: 执行工具
    end

2.2 Hook 事件类型全览

截至 2026 年初,Claude Code 支持以下 Hook 事件:

事件 触发时机 典型用途
PreToolUse 工具执行之前 拦截危险操作、参数校验
PostToolUse 工具执行之后 自动格式化、日志记录、触发构建
Notification Claude 通知用户时 自定义通知渠道(Slack/钉钉)
Stop Claude 完成回复时 生成报告、触发 CI
SubagentStop 子 Agent 完成时 聚合子任务结果

2.3 Hook 配置结构

Hooks 配置在 settings.json 的 hooks 字段中:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 /path/to/security-guard.py"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $CLAUDE_FILE_PATH 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

字段说明:

2.4 Hook 的 JSON 输入格式

Hook 脚本通过 stdin 接收 JSON 数据:

{
  "tool_name": "Bash",
  "tool_input": {
    "command": "rm -rf /tmp/test",
    "description": "清理临时文件"
  },
  "session_id": "abc123"
}

PreToolUse 的退出码语义:

退出码 含义 行为
0 放行 工具正常执行
2 拦截 阻止执行,stdout 内容作为反馈给 Claude
其他 / 超时 忽略 工具正常执行(安全失败策略)

2.5 实战:五个生产级安全 Hook

Hook 1:危险命令拦截器

#!/usr/bin/env python3
"""danger-guard.py — 拦截危险的 Bash 命令"""
import sys, json

DANGEROUS_PATTERNS = [
    "rm -rf /", "rm -rf ~", "rm -rf /*",
    "sudo rm", ":(){ :|:& };:",  # fork bomb
    "dd if=/dev/zero",
    "mkfs.", "format ",
    "> /dev/sd", "chmod -R 777 /",
    "curl * | bash", "curl * | sh",
    "wget * | bash", "wget * | sh",
]

def check(data):
    if data.get("tool_name") != "Bash":
        sys.exit(0)

    cmd = data.get("tool_input", {}).get("command", "")

    for pattern in DANGEROUS_PATTERNS:
        # 简单的通配符匹配
        if "*" in pattern:
            parts = pattern.split("*")
            if all(p in cmd for p in parts if p):
                print(f"⛔ 危险命令已被拦截!匹配模式: {pattern}")
                print(f"   命令: {cmd}")
                sys.exit(2)
        elif pattern in cmd:
            print(f"⛔ 危险命令已被拦截!匹配模式: {pattern}")
            print(f"   命令: {cmd}")
            sys.exit(2)

    sys.exit(0)  # 放行

data = json.load(sys.stdin)
check(data)

配置:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/danger-guard.py"
          }
        ]
      }
    ]
  }
}

Hook 2:敏感文件保护

#!/usr/bin/env python3
"""file-guard.py — 保护敏感文件不被修改或删除"""
import sys, json, re

PROTECTED_PATTERNS = [
    r"\.env($|\.|$)", r"\.env\.",
    r"\.pem$", r"\.key$", r"\.p12$",
    r"credentials", r"secrets?[/\\]",
    r"id_rsa", r"id_ed25519",
    r"\.ssh[/\\]",
    r"\.gnupg[/\\]",
    r"\.aws[/\\]credentials",
]

def check(data):
    tool = data.get("tool_name", "")
    if tool not in ("Edit", "Write", "Bash"):
        sys.exit(0)

    if tool == "Bash":
        cmd = data.get("tool_input", {}).get("command", "")
        # 检查是否涉及敏感文件的删除或覆盖
        for p in PROTECTED_PATTERNS:
            if re.search(p, cmd):
                print(f"🔒 操作被阻止:涉及敏感文件/目录 (模式: {p})")
                print(f"   命令: {cmd}")
                sys.exit(2)
        sys.exit(0)

    file_path = data.get("tool_input", {}).get("file_path", "")
    for p in PROTECTED_PATTERNS:
        if re.search(p, file_path):
            print(f"🔒 文件被保护,禁止 {tool} 操作: {file_path}")
            sys.exit(2)

    sys.exit(0)

data = json.load(sys.stdin)
check(data)

Hook 3:自动代码格式化

#!/usr/bin/env python3
"""auto-format.py — 文件编辑后自动格式化"""
import sys, json, subprocess, os

def format_file(data):
    tool = data.get("tool_name", "")
    if tool not in ("Edit", "Write"):
        sys.exit(0)

    file_path = data.get("tool_input", {}).get("file_path", "")
    if not file_path or not os.path.exists(file_path):
        sys.exit(0)

    ext = os.path.splitext(file_path)[1]

    # 根据文件类型选择格式化工具
    formatters = {
        ".js": ["npx", "prettier", "--write"],
        ".ts": ["npx", "prettier", "--write"],
        ".jsx": ["npx", "prettier", "--write"],
        ".tsx": ["npx", "prettier", "--write"],
        ".css": ["npx", "prettier", "--write"],
        ".json": ["npx", "prettier", "--write"],
        ".py": ["python3", "-m", "black"],
        ".go": ["gofmt", "-w"],
        ".rs": ["rustfmt"],
    }

    formatter = formatters.get(ext)
    if formatter:
        try:
            subprocess.run(
                formatter + [file_path],
                capture_output=True, timeout=10
            )
        except Exception:
            pass  # 格式化失败不影响主流程

    sys.exit(0)

data = json.load(sys.stdin)
format_file(data)

Hook 4:Git 仓库保护

#!/usr/bin/env python3
"""git-guard.py — 防止在 main/master 分支上直接修改"""
import sys, json, subprocess

def check(data):
    if data.get("tool_name") != "Bash":
        sys.exit(0)

    cmd = data.get("tool_input", {}).get("command", "")

    # 只检查 git commit / git push 操作
    if "git commit" not in cmd and "git push" not in cmd:
        sys.exit(0)

    try:
        result = subprocess.run(
            ["git", "rev-parse", "--abbrev-ref", "HEAD"],
            capture_output=True, text=True, timeout=5
        )
        branch = result.stdout.strip()

        if branch in ("main", "master"):
            print(f"🛡️ 禁止在 {branch} 分支上直接 commit/push!")
            print(f"   请创建新分支: git checkout -b feature/xxx")
            sys.exit(2)
    except Exception:
        pass

    sys.exit(0)

data = json.load(sys.stdin)
check(data)

Hook 5:操作审计日志

#!/usr/bin/env python3
"""audit-logger.py — 记录所有工具调用到审计日志"""
import sys, json, os
from datetime import datetime

LOG_FILE = os.path.expanduser("~/.claude/audit.log")

def log(data):
    entry = {
        "timestamp": datetime.now().isoformat(),
        "tool": data.get("tool_name"),
        "input_summary": str(data.get("tool_input", {}))[:500],
        "session_id": data.get("session_id", "unknown"),
    }

    with open(LOG_FILE, "a") as f:
        f.write(json.dumps(entry, ensure_ascii=False) + "\n")

    sys.exit(0)  # 只记录,不拦截

data = json.load(sys.stdin)
log(data)

2.6 组合所有 Hook 的完整配置

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/danger-guard.py"
          },
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/git-guard.py"
          }
        ]
      },
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/file-guard.py"
          }
        ]
      },
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/audit-logger.py"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/auto-format.py"
          }
        ]
      }
    ]
  }
}

注意:同一个 matcher 下可以有多个 Hook,它们按顺序执行。任何一个返回 exit 2 就会拦截。


第三章:权限与 Hooks 的协同防御

3.1 纵深防御架构

权限系统和 Hooks 不是二选一的关系,而是多层防线:

flowchart TB
    subgraph "第一层:静态权限防线"
        A[工具调用] --> B{Deny 规则匹配?}
        B -->|是| C[❌ 静默拒绝]
        B -->|否| D{Allow 规则匹配?}
        D -->|是| E[✅ 自动放行]
        D -->|否| F{PreToolUse Hook}
    end

    subgraph "第二层:动态 Hook 防线"
        F -->|exit 2| G[❌ Hook 拦截]
        F -->|exit 0| H{用户确认}
    end

    subgraph "第三层:人工确认"
        H -->|拒绝| I[❌ 用户拒绝]
        H -->|允许| J[执行工具]
    end

    subgraph "第四层:后置处理"
        J --> K[PostToolUse Hook]
        K --> L[日志 / 格式化 / 验证]
    end

    style C fill:#ff6b6b
    style G fill:#ff6b6b
    style I fill:#ff6b6b
    style E fill:#51cf66
    style J fill:#51cf66
    style L fill:#74c0fc

3.2 配置策略矩阵

不同场景需要不同的安全级别:

场景 权限策略 Hook 策略 推荐模式
个人学习/实验 宽松 allow + 少量 deny 审计日志 --auto-accept-edits
团队项目开发 精确 allow + deny 敏感操作 全部 5 个 Hook 标准 Ask 模式
CI/CD 自动化 严格 allow 白名单 守卫 + 审计 --dangerously-skip-permissions + Docker
安全审计 严格 deny + 最小 allow 全 Hook + 额外验证 最严格模式

3.3 实战:团队项目安全配置模板

创建 .claude/settings.json(提交到 Git,团队共享):

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "WebSearch",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(npm test *)",
      "Bash(npm run lint *)",
      "Bash(npm run build *)",
      "Bash(npm run typecheck *)",
      "Bash(npx *)",
      "Bash(node *)",
      "Bash(ls *)",
      "Bash(cat *)",
      "Bash(head *)",
      "Bash(tail *)",
      "Bash(find *)",
      "Bash(grep *)",
      "Bash(wc *)",
      "Bash(echo *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Bash(chmod 777 *)",
      "Bash(curl * | sh*)",
      "Bash(curl * | bash*)",
      "Bash(wget * | sh*)",
      "Bash(docker rm *)",
      "Bash(kubectl delete *)",
      "Bash(psql *)",
      "Bash(mysql *)",
      "Bash(mongosh *)",
      "Write(.env*)",
      "Write(*.pem)",
      "Write(*.key)",
      "Write(*.secret*)",
      "Edit(.env*)",
      "Edit(*.pem)",
      "Edit(*.key)",
      "Edit(*.secret*)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 scripts/hooks/danger-guard.py"
          }
        ]
      },
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 scripts/hooks/file-guard.py"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 scripts/hooks/auto-format.py"
          }
        ]
      }
    ]
  }
}

创建 .claude/settings.local.json(不提交到 Git,个人覆盖):

{
  "permissions": {
    "allow": [
      "Bash(docker *)",
      "Bash(kubectl *)",
      "Bash(terraform *)",
      "Bash(aws *)"
    ]
  }
}

在 .gitignore 中添加:

.claude/settings.local.json

第四章:Docker 沙箱——终极隔离方案

4.1 为什么需要沙箱?

权限和 Hooks 保护的是代码层面的操作安全,但无法防御以下场景: - Claude Code 进程被利用执行任意代码 - 文件系统被越权访问 - 网络被用来攻击内网服务 - 环境变量中的密钥被读取

Docker 沙箱提供了操作系统级别的隔离,即使 Claude Code 被完全控制,攻击者也只能在容器内部活动。

4.2 沙箱方案对比

flowchart LR
    subgraph "方案A:内置沙箱"
        A1[Claude Code] --> A2[Seatbelt / Landlock]
        A2 --> A3[受限文件系统]
    end

    subgraph "方案B:Docker 容器"
        B1[Claude Code] --> B2[Docker Container]
        B2 --> B3[命名空间隔离]
        B2 --> B4[网络隔离]
        B2 --> B5[资源限制]
    end

    subgraph "方案C:Dev Container"
        C1[Claude Code] --> C2[VS Code Dev Container]
        C2 --> C3[完整开发环境]
    end

    style A2 fill:#ffd43b
    style B2 fill:#51cf66
    style C2 fill:#74c0fc
方案 隔离级别 易用性 适用场景
内置沙箱(macOS Seatbelt / Linux Landlock) 中 ⭐⭐⭐⭐⭐ 个人开发、macOS 用户
Docker 容器 高 ⭐⭐⭐ CI/CD、团队共享、Linux 服务器
Dev Container 高 ⭐⭐⭐⭐ VS Code 用户、团队项目

4.3 实战:从零搭建 Docker 沙箱

Step 1:创建 Dockerfile

# claude-sandbox/Dockerfile
FROM node:20-slim

# 安装基础工具
RUN apt-get update && apt-get install -y \
    git \
    python3 \
    python3-pip \
    curl \
    jq \
    && rm -rf /var/lib/apt/lists/*

# 安装 Claude Code
RUN npm install -g @anthropic-ai/claude-code

# 创建非 root 用户
RUN useradd -m -s /bin/bash claude
USER claude
WORKDIR /home/claude/workspace

# 设置安全的环境变量
ENV NODE_ENV=development
ENV CLAUDE_CODE_SANDBOX=true

ENTRYPOINT ["claude"]

Step 2:创建 docker-compose.yml

# claude-sandbox/docker-compose.yml
version: '3.8'

services:
  claude-sandbox:
    build: .
    container_name: claude-code-sandbox
    # 关键安全配置
    security_opt:
      - no-new-privileges:true
    read_only: false
    # 资源限制
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
        reservations:
          cpus: '0.5'
          memory: 512M
    # 网络隔离(仅 DNS,无外网)
    networks:
      - claude-net
    # 文件系统挂载(只挂载项目目录)
    volumes:
      - ../:/home/claude/workspace:rw
      - claude-home:/home/claude/.claude
    # 环境变量(从 .env 传入 API Key)
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
    # 禁止特权升级
    cap_drop:
      - ALL
    stdin_open: true
    tty: true

networks:
  claude-net:
    driver: bridge
    internal: false  # 设为 true 可完全禁止外网

volumes:
  claude-home:

Step 3:创建安全配置

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Bash(git *)",
      "Bash(npm *)",
      "Bash(npx *)",
      "Bash(node *)",
      "Bash(python3 *)",
      "Bash(ls *)",
      "Bash(cat *)",
      "Bash(find *)",
      "Bash(echo *)",
      "Bash(mkdir *)",
      "Bash(test *)",
      "Edit(src/**)",
      "Edit(tests/**)",
      "Write(src/**)",
      "Write(tests/**)"
    ],
    "deny": [
      "Bash(sudo *)",
      "Bash(su *)",
      "Bash(rm -rf /)",
      "Bash(curl * | *)",
      "Bash(wget * | *)",
      "Bash(apt *)",
      "Bash(yum *)",
      "Bash(pip install *)",
      "Bash(npm install -g *)",
      "Write(*)",
      "Edit(*)"
    ]
  }
}

Step 4:启动和管理沙箱

# 构建镜像
cd claude-sandbox
docker compose build

# 交互式启动(连接到终端)
docker compose run --rm claude-sandbox

# 启动时传入项目特定的权限配置
docker compose run --rm \
  -v $(pwd)/sandbox-settings.json:/home/claude/.claude/settings.json:ro \
  claude-sandbox

# 以 -p 模式执行任务(非交互式)
docker compose run --rm claude-sandbox \
  -p "分析 src/ 目录的代码质量,给出改进建议"

# 执行完成后自动销毁容器
docker compose down

Step 5:网络隔离配置(可选但推荐)

如果需要禁止 Claude Code 访问外网,但允许访问特定 API:

# 在 docker-compose.yml 中替换 networks 配置
networks:
  claude-net:
    driver: bridge
    internal: true  # 完全禁止外网访问
    # 需要额外配置 DNS 和 API 代理

如果需要允许访问 Anthropic API 但禁止其他外网:

services:
  claude-sandbox:
    networks:
      - claude-net
    dns:
      - 8.8.8.8  # 允许 DNS 解析

  api-proxy:
    image: nginx:alpine
    networks:
      - claude-net
      - external-net
    # 配置 nginx 仅代理 api.anthropic.com

networks:
  claude-net:
    internal: true
  external-net:
    driver: bridge

4.4 无 Docker 的轻量替代:内置沙箱模式

在不方便使用 Docker 的环境(如 macOS),可以使用 Claude Code 内置的沙箱:

# macOS:使用 Seatbelt 沙箱
claude --sandbox

# 或在 settings.json 中配置
# macOS 会自动使用 Seatbelt
# Linux 会使用 Landlock LSM

内置沙箱的限制: - macOS Seatbelt:限制文件系统访问、禁止网络(可配置) - Linux Landlock:限制文件系统访问(需要内核 5.13+) - 不如 Docker 隔离彻底,但零配置即用


第五章:完整实战项目——安全加固的 Claude Code 开发环境

5.1 项目目标

为一个 5 人前端团队搭建 Claude Code 安全开发环境,要求: 1. 团队成员共享安全策略 2. 个人可自定义覆盖 3. CI/CD 中可无人值守运行 4. 敏感文件绝对保护 5. 所有操作可审计

5.2 项目结构

my-project/
├── .claude/
│   ├── settings.json          # 团队共享安全策略(提交 Git)
│   ├── hooks/
│   │   ├── danger-guard.py    # 危险命令拦截
│   │   ├── file-guard.py      # 敏感文件保护
│   │   ├── git-guard.py       # Git 分支保护
│   │   ├── auto-format.py     # 自动格式化
│   │   └── audit-logger.py    # 审计日志
│   └── audit/                 # 审计日志存储(gitignore)
│       └── .gitkeep
├── .claude-sandbox/           # Docker 沙箱配置
│   ├── Dockerfile
│   ├── docker-compose.yml
│   └── sandbox-settings.json  # 沙箱内的权限配置
├── .github/
│   └── workflows/
│       └── claude-review.yml  # CI 中使用 Claude Code
├── CLAUDE.md                  # 项目指令文件
├── .gitignore
├── package.json
└── src/

5.3 完整的 CLAUDE.md 配置

# Project: MyProject

## Tech Stack
- React 18 + TypeScript
- Vite
- TailwindCSS
- Vitest + React Testing Library

## Architecture
- src/components/ — UI 组件
- src/hooks/ — 自定义 React Hooks
- src/services/ — API 调用层
- src/utils/ — 工具函数
- tests/ — 测试文件

## Rules
- 所有新代码必须包含对应测试
- 使用 TypeScript strict mode
- 组件使用函数式组件 + Hooks
- 不要修改 package.json 中的依赖版本
- 不要删除 .env.example 中的变量

## Commands
- 构建: npm run build
- 测试: npm run test
- Lint: npm run lint
- 类型检查: npm run typecheck

5.4 CI/CD 集成:GitHub Actions 安全配置

# .github/workflows/claude-review.yml
name: Claude Code Review

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  claude-review:
    runs-on: ubuntu-latest
    container:
      image: node:20-slim
      options: --user root

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: |
          npm ci
          npm install -g @anthropic-ai/claude-code

      - name: Run Claude Code Review
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          claude -p "Review the changes in this PR for:
          1. Security vulnerabilities
          2. Code quality issues
          3. Missing tests
          4. Breaking changes

          Be specific and cite file paths." \
            --allowedTools "Read,Glob,Grep,Bash(git diff *)" \
            --max-turns 10

关键安全措施: - 使用 --allowedTools 限制可用工具为只读 - --max-turns 防止无限循环 - API Key 存储在 GitHub Secrets 中 - 容器隔离运行

5.5 验证安全配置

创建一个验证脚本:

#!/bin/bash
# scripts/verify-security.sh — 验证 Claude Code 安全配置

set -e

echo "🔍 验证 Claude Code 安全配置..."
echo ""

# 1. 检查 settings.json 是否存在且语法正确
echo "✅ 检查 settings.json..."
if [ -f ".claude/settings.json" ]; then
    jq empty .claude/settings.json 2>/dev/null && echo "  JSON 语法正确" || echo "  ❌ JSON 语法错误!"
else
    echo "  ❌ .claude/settings.json 不存在!"
fi

# 2. 检查 deny 规则是否覆盖关键危险操作
echo ""
echo "✅ 检查 deny 规则覆盖..."
DENOULEMENTS=("rm -rf" "sudo" "chmod 777" "curl.*bash")
for pattern in "${DENOULEMENTS[@]}"; do
    if grep -q "$pattern" .claude/settings.json 2>/dev/null; then
        echo "  ✓ $pattern 已被 deny"
    else
        echo "  ⚠ $pattern 未被 deny"
    fi
done

# 3. 检查 Hook 脚本是否存在且可执行
echo ""
echo "✅ 检查 Hook 脚本..."
for hook in danger-guard file-guard git-guard auto-format audit-logger; do
    if [ -f ".claude/hooks/${hook}.py" ]; then
        echo "  ✓ ${hook}.py 存在"
        python3 -m py_compile ".claude/hooks/${hook}.py" 2>/dev/null && echo "    语法正确" || echo "    ❌ 语法错误"
    else
        echo "  ⚠ ${hook}.py 不存在"
    fi
done

# 4. 检查 Docker 沙箱配置
echo ""
echo "✅ 检查 Docker 沙箱..."
if [ -f ".claude-sandbox/Dockerfile" ]; then
    echo "  ✓ Dockerfile 存在"
    if grep -q "cap_drop" .claude-sandbox/docker-compose.yml 2>/dev/null; then
        echo "  ✓ 已配置 cap_drop"
    else
        echo "  ⚠ 未配置 cap_drop"
    fi
    if grep -q "no-new-privileges" .claude-sandbox/docker-compose.yml 2>/dev/null; then
        echo "  ✓ 已配置 no-new-privileges"
    else
        echo "  ⚠ 未配置 no-new-privileges"
    fi
else
    echo "  ⚠ Docker 沙箱未配置"
fi

# 5. 检查 .gitignore 是否排除了敏感文件
echo ""
echo "✅ 检查 .gitignore..."
for item in "settings.local.json" ".env"; do
    if grep -q "$item" .gitignore 2>/dev/null; then
        echo "  ✓ $item 已被 gitignore"
    else
        echo "  ⚠ $item 未被 gitignore"
    fi
done

echo ""
echo "🎉 安全配置验证完成!"

运行验证:

chmod +x scripts/verify-security.sh
./scripts/verify-security.sh

第六章:安全事件响应与故障排查

6.1 常见安全问题排查

问题现象 可能原因 排查命令 解决方案
Hook 不触发 脚本不可执行或路径错误 ls -la .claude/hooks/ chmod +x .claude/hooks/*.py
所有操作被拦截 Hook 脚本有 Bug 检查审计日志 python3 .claude/hooks/danger-guard.py <<< '{"tool_name":"Read","tool_input":{}}'
Docker 容器启动失败 权限不足 docker compose logs 确保用户在 docker 组
API Key 泄露 settings.json 包含密钥 git log --all --full-history -- '*.env' 使用 Git history 重写
Claude Code 异常慢 Docker 资源不足 docker stats 增大内存/CPU 限制

6.2 审计日志分析

# 查看今天的审计日志
cat ~/.claude/audit.log | jq -c 'select(.timestamp | startswith("2026-06-11"))'

# 统计各工具调用次数
cat ~/.claude/audit.log | jq -r '.tool' | sort | uniq -c | sort -rn

# 查找涉及敏感文件的操作
cat ~/.claude/audit.log | jq -c 'select(.input_summary | test("\\.env|\\.pem|\\.key|secret"))'

# 查看特定会话的所有操作
cat ~/.claude/audit.log | jq -c 'select(.session_id == "abc123")'

6.3 安全清单(Security Checklist)

在生产环境部署 Claude Code 前,逐项确认:

□ settings.json 配置了 deny 规则覆盖 rm -rf、sudo、curl|bash
□ 敏感文件 (.env, .pem, .key) 被 deny 保护
□ PreToolUse Hook 已部署并测试
□ 审计日志已启用
□ API Key 不在代码仓库中
□ settings.local.json 在 .gitignore 中
□ Docker 沙箱已配置资源限制
□ Docker 容器使用非 root 用户
□ Docker 已配置 cap_drop: ALL
□ 网络策略已按需配置(internal: true 或 API 代理)
□ CI/CD 中 Claude Code 使用只读工具
□ 定期审查审计日志

第七章:进阶主题

7.1 Managed Settings(企业级策略下发)

企业团队可以通过 Anthropic 的管理后台(Anthropic Console)下发不可覆盖的安全策略,确保即使开发者修改本地 settings.json 也无法绕过:

{
  "managedSettings": {
    "permissions": {
      "deny": [
        "Bash(sudo *)",
        "Bash(rm -rf *)",
        "Bash(curl * | *)",
        "Write(.env*)",
        "Write(*.pem)"
      ]
    }
  }
}

Managed settings 的优先级高于所有本地配置,且用户无法修改。

7.2 多环境配置策略

# 开发环境:宽松
claude --settings .claude/settings.dev.json

# 测试环境:标准
claude --settings .claude/settings.test.json

# 生产环境:严格
claude --settings .claude/settings.prod.json

或使用环境变量驱动:

#!/usr/bin/env python3
"""env-settings.py — 根据环境变量选择配置"""
import os, json, shutil

env = os.getenv("CLAUDE_ENV", "dev")
settings_files = {
    "dev": "settings.dev.json",
    "staging": "settings.staging.json",
    "prod": "settings.prod.json",
}

src = f".claude/profiles/{settings_files[env]}"
dst = ".claude/settings.json"
shutil.copy2(src, dst)
print(f"已切换到 {env} 环境配置")

7.3 与 IDE 安全集成

VS Code 和 JetBrains 的 Claude Code 插件会读取同一套 settings.json 配置。确保: - IDE 插件版本与 CLI 版本一致 - IDE 的 workspace settings 不覆盖安全策略 - 在 IDE 中也启用审计日志


延伸阅读

训练营适用性评估

评估维度 说明
适合训练营类型 企业内训(AI 安全专题)、高级开发者训练营、DevOps 安全培训
学员基础要求 已完成 Claude Code 入门 + 至少一个实战项目
预计教学时长 3-4 小时(讲解 1.5h + 动手实践 1.5h + 讨论 1h)
实验环境要求 每人一台 Linux/macOS 机器 + Docker 环境
核心产出 学员带走一套完整的安全配置模板 + 5 个 Hook 脚本 + Docker 沙箱配置

参考来源

  1. Automate actions with hooks - Claude Code Docs — Anthropic 官方 Hooks 使用指南,涵盖 PreToolUse、PostToolUse 等生命周期事件配置
  2. Configure permissions - Claude Code Docs — Anthropic 官方权限配置文档,详细说明 allow/deny 语法和层级结构
  3. Choose a sandbox environment - Claude Code Docs — Anthropic 官方沙箱方案对比,覆盖内置沙箱、Docker、Dev Container
  4. Claude Code Hooks: Complete Guide with 20+ Examples (2026) — 社区维护的 Hooks 完整指南,提供生产级配置示例
  5. Docker Sandboxes: Run Claude Code Safely — Docker 官方博客,详解如何用 microVM 和容器隔离安全运行 AI 编程 Agent

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入