{
  "metadata": {
    "id": "ch39",
    "title": "第39章 安全与权限管理",
    "volume": "vol10",
    "volume_title": "生产级Agent平台",
    "word_count": 1921,
    "difficulty": "advanced",
    "prerequisites": [
      "ch11",
      "ch36"
    ],
    "key_concepts": [
      "概述：Agent 系统的独特安全挑战",
      "身份认证",
      "认证方案选型",
      "JWT 实现",
      "API Key 管理",
      "授权模型",
      "RBAC + ABAC 混合模型",
      "权限定义与策略引擎",
      "API 安全",
      "输入验证与清洗",
      "Rate Limiting（安全角度）",
      "数据加密",
      "加密策略",
      "TLS 配置",
      "Prompt 安全"
    ],
    "learning_objectives": [],
    "estimated_tokens": 1153,
    "source_file": "vol10/ch39_安全与权限管理.md"
  },
  "overview": "",
  "sections": [
    {
      "id": "39.1",
      "title": "39.1 概述：Agent 系统的独特安全挑战",
      "level": 2,
      "content": "Agent 系统与传统 Web 应用在安全上有本质区别。传统应用的安全边界相对清晰：用户输入 → 处理 → 输出。但 Agent 系统引入了 LLM 作为\"决策中枢\"，带来了全新的攻击面：\n\n1. **Prompt 注入**：攻击者通过精心构造的输入操纵 Agent 的行为\n2. **间接 Prompt 注入**：通过工具返回的数据或文档内容注入恶意指令\n3. **权限放大**：Agent 可能被诱骗执行超出授权范围的操作\n4. **数据泄露**：Agent 可能将敏感信息包含在响应中\n5. **模型服务滥用**：LLM API 被滥用或劫持",
      "subsections": []
    },
    {
      "id": "39.2",
      "title": "39.2 身份认证",
      "level": 2,
      "content": "",
      "subsections": [
        {
          "id": "39.2.1",
          "title": "39.2.1 认证方案选型",
          "content": "| 方案 | 适用场景 | 安全性 | 复杂度 | 令牌管理 |\n|------|----------|--------|--------|----------|\n| Session + Cookie | Web 应用 | 中 | 低 | 服务端管理 |\n| JWT (RS256) | API + Web | 高 | 中 | 无状态 |\n| OAuth 2.0 | 第三方集成 | 高 | 高 | 标准化 |\n| API Key | 服务间通信 | 中 | 低 | 静态密钥 |\n| mTLS | 服务间通信 | 极高 | 高 | 证书管理 |\n\n**推荐组合**：外部用户使用 OAuth 2.0 + JWT，内部服务使用 mTLS + API Key。"
        },
        {
          "id": "39.2.2",
          "title": "39.2.2 JWT 实现",
          "content": ""
        },
        {
          "id": "39.2.3",
          "title": "39.2.3 API Key 管理",
          "content": ""
        }
      ]
    },
    {
      "id": "39.3",
      "title": "39.3 授权模型",
      "level": 2,
      "content": "",
      "subsections": [
        {
          "id": "39.3.1",
          "title": "39.3.1 RBAC + ABAC 混合模型",
          "content": "Agent 平台推荐使用 RBAC（基于角色）与 ABAC（基于属性）的混合授权模型："
        },
        {
          "id": "39.3.2",
          "title": "39.3.2 权限定义与策略引擎",
          "content": ""
        }
      ]
    },
    {
      "id": "39.4",
      "title": "39.4 API 安全",
      "level": 2,
      "content": "",
      "subsections": [
        {
          "id": "39.4.1",
          "title": "39.4.1 输入验证与清洗",
          "content": ""
        },
        {
          "id": "39.4.2",
          "title": "39.4.2 Rate Limiting（安全角度）",
          "content": ""
        }
      ]
    },
    {
      "id": "39.5",
      "title": "39.5 数据加密",
      "level": 2,
      "content": "",
      "subsections": [
        {
          "id": "39.5.1",
          "title": "39.5.1 加密策略",
          "content": ""
        },
        {
          "id": "39.5.2",
          "title": "39.5.2 TLS 配置",
          "content": ""
        }
      ]
    },
    {
      "id": "39.6",
      "title": "39.6 Prompt 安全",
      "level": 2,
      "content": "",
      "subsections": [
        {
          "id": "39.6.1",
          "title": "39.6.1 Prompt 注入防御",
          "content": "Prompt 注入是 Agent 系统最独特的安全威胁。防御需要多层策略："
        },
        {
          "id": "39.6.2",
          "title": "39.6.2 工具执行沙箱",
          "content": "Agent 调用工具时必须在安全的沙箱环境中执行："
        }
      ]
    },
    {
      "id": "39.7",
      "title": "39.7 合规审计",
      "level": 2,
      "content": "",
      "subsections": [
        {
          "id": "39.7.1",
          "title": "39.7.1 审计日志设计",
          "content": ""
        },
        {
          "id": "39.7.2",
          "title": "39.7.2 合规检查清单",
          "content": "| 合规领域 | 要求 | 实现措施 |\n|----------|------|----------|\n| 数据隐私 (GDPR/个人信息保护法) | 用户有权删除其数据 | 数据删除 API + 自动清理 |\n| 数据存储 | 敏感数据加密存储 | AES-256-GCM 字段级加密 |\n| 传输安全 | 数据传输加密 | TLS 1.3 强制 |\n| 访问控制 | 最小权限原则 | RBAC + ABAC 混合模型 |\n| 审计追踪 | 所有操作可追溯 | 完整审计日志 |\n| 数据保留 | 数据保留期限管理 | ILM 生命周期管理 |\n| AI 透明度 | AI 生成内容标识 | 响应中标注\"AI 生成\" |\n| Prompt 安全 | 防止 Prompt 注入 | 多层安全防护 |"
        }
      ]
    },
    {
      "id": "39.8",
      "title": "39.8 安全最佳实践",
      "level": 2,
      "content": "",
      "subsections": [
        {
          "id": "39.8.1",
          "title": "39.8.1 安全开发规范",
          "content": "1. **密钥管理**\n   - 密钥不硬编码在代码中\n   - 使用 KMS（如 HashiCorp Vault、AWS KMS）管理密钥\n   - 生产密钥与开发密钥严格分离\n   - 定期轮换密钥\n\n2. **依赖安全**\n   ```bash\n   # 定期扫描依赖漏洞\n   pip install safety bandit\n   safety check --json\n   bandit -r src/ -f json\n   ```\n\n3. **安全编码原则**\n   - 所有用户输入必须验证和清洗\n   - SQL 使用参数化查询\n   - 文件上传限制类型和大小\n   - 敏感数据不记录在日志中"
        },
        {
          "id": "39.8.2",
          "title": "39.8.2 安全响应流程",
          "content": ""
        }
      ]
    },
    {
      "id": "39.9",
      "title": "39.9 本章小结",
      "level": 2,
      "content": "本章全面介绍了 Agent 平台的安全与权限管理：\n\n1. **身份认证**：OAuth 2.0 + JWT + API Key 的多层级认证方案\n2. **授权模型**：RBAC + ABAC 混合模型，支持细粒度权限控制\n3. **API 安全**：输入验证、速率限制、安全头部\n4. **数据加密**：传输加密（TLS 1.3）+ 存储加密（AES-256-GCM）+ 密钥管理\n5. **Prompt 安全**：注入检测、输入清洗、输出过滤、工具沙箱\n6. **合规审计**：完整的审计日志 + 合规检查清单\n\n安全是一个持续对抗的过程。Agent 系统的安全挑战比传统系统更加复杂，需要团队持续关注、学习和改进。下一章我们将讨论 CI/CD 与版本管理——让安全和质量的保障自动化。",
      "subsections": []
    }
  ],
  "code_blocks": [
    {
      "id": "code-1",
      "language": "mermaid",
      "description": "5. 模型服务滥用：LLM API 被滥用或劫持",
      "code": "graph TB\n    Attack[攻击面]\n    Attack --> PI[Prompt 注入<br/>直接/间接]\n    Attack --> PA[权限放大<br/>越权操作]\n    Attack --> DL[数据泄露<br/>敏感信息外泄]\n    Attack --> DD[拒绝服务<br/>资源耗尽]\n    Attack --> SP[供应链攻击<br/>恶意 Skill/工具]\n    \n    PI --> Defense[Prompt 安全防护]\n    PA --> Defense\n    DL --> Defense\n    DD --> Defense\n    SP --> Defense\n    \n    Defense --> Auth[身份认证]\n    Defense --> AuthZ[授权模型]\n    Defense --> API[API 安全]\n    Defense --> Enc[数据加密]\n    Defense --> Audit[合规审计]",
      "section_ref": "39.1",
      "runnable": false,
      "dependencies": []
    },
    {
      "id": "code-2",
      "language": "python",
      "description": "推荐组合：外部用户使用 OAuth 2.0 + JWT，内部服务使用 mTLS + API Key。",
      "code": "# auth_service.py\nimport jwt\nimport hashlib\nimport time\nfrom datetime import datetime, timedelta, timezone\nfrom typing import Optional\nfrom dataclasses import dataclass\n\n@dataclass\nclass AuthConfig:\n    jwt_secret: str          # HMAC 密钥或 RSA 私钥路径\n    algorithm: str = \"RS256\"  # RS256(非对称) 或 HS256(对称)\n    access_token_ttl: int = 900       # 15 分钟\n    refresh_token_ttl: int = 604800   # 7 天\n    issuer: str = \"agent-platform\"\n\n@dataclass\nclass TokenPayload:\n    user_id: str\n    email: str\n    tenant_id: str\n    roles: list[str]\n    tier: str  # free, pro, enterprise\n\nclass AuthService:\n    \"\"\"认证服务\"\"\"\n    \n    def __init__(self, config: AuthConfig, db):\n        self.config = config\n        self.db = db\n    \n    def generate_tokens(self, payload: TokenPayload) -> dict:\n        \"\"\"生成 Access Token + Refresh Token\"\"\"\n        now = datetime.now(timezone.utc)\n        \n        access_payload = {\n            \"sub\": payload.user_id,\n            \"email\": payload.email,\n            \"tenant_id\": payload.tenant_id,\n            \"roles\": payload.roles,\n            \"tier\": payload.tier,\n            \"iss\": self.config.issuer,\n            \"iat\": now,\n            \"exp\": now + timedelta(seconds=self.config.access_token_ttl),\n            \"type\": \"access\",\n            \"jti\": self._generate_jti(),  # JWT ID，用于吊销\n        }\n        \n        refresh_payload = {\n            \"sub\": payload.user_id,\n            \"iss\": self.config.issuer,\n            \"iat\": now,\n            \"exp\": now + timedelta(seconds=self.config.refresh_token_ttl),\n            \"type\": \"refresh\",\n            \"jti\": self._generate_jti(),\n        }\n        \n        access_token = jwt.encode(\n            access_payload, self._get_signing_key(),\n            algorithm=self.config.algorithm\n        )\n        refresh_token = jwt.encode(\n            refresh_payload, self._get_signing_key(),\n            algorithm=self.config.algorithm\n        )\n        \n        return {\n            \"access_token\": access_token,\n            \"refresh_token\": refresh_token,\n            \"expires_in\": self.config.access_token_ttl,\n            \"token_type\": \"Bearer\"\n        }\n    \n    def verify_token(self, token: str) -> Optional[dict]:\n        \"\"\"验证并解码 Token\"\"\"\n        try:\n            payload = jwt.decode(\n                token, self._get_verification_key(),\n                algorithms=[self.config.algorithm],\n                issuer=self.config.issuer\n            )\n            \n            # 检查是否已被吊销\n            if self._is_token_revoked(payload.get(\"jti\")):\n                return None\n            \n            return payload\n        except jwt.ExpiredSignatureError:\n            return None\n        except jwt.InvalidTokenError:\n            return None\n    \n    def revoke_token(self, jti: str):\n        \"\"\"吊销 Token（加入黑名单）\"\"\"\n        # 将 JTI 写入 Redis，设置 TTL 与 Token 过期时间一致\n        self.redis.setex(\n            f\"revoked:{jti}\",\n            self.config.refresh_token_ttl,\n            \"1\"\n        )\n    \n    def _is_token_revoked(self, jti: str) -> bool:\n        \"\"\"检查 Token 是否被吊销\"\"\"\n        return bool(self.redis.exists(f\"revoked:{jti}\"))\n    \n    def _get_signing_key(self):\n        if self.config.algorithm == \"HS256\":\n            return self.config.jwt_secret\n        else:\n            # RS256: 加载私钥文件\n            with open(self.config.jwt_secret, 'r') as f:\n                return f.read()\n    \n    def _get_verification_key(self):\n        if self.config.algorithm == \"HS256\":\n            return self.config.jwt_secret\n        else:\n            # RS256: 加载公钥文件\n            pub_key_path = self.config.jwt_secret.replace(\".key\", \".pub\")\n            with open(pub_key_path, 'r') as f:\n                return f.read()\n    \n    def _generate_jti(self) -> str:\n        \"\"\"生成唯一的 JWT ID\"\"\"\n        raw = f\"{time.time()}-{id(self)}-{time.monotonic_ns()}\"\n        return hashlib.sha256(raw.encode()).hexdigest()[:32]",
      "section_ref": "39.2.2",
      "runnable": true,
      "dependencies": [
        "jwt"
      ]
    },
    {
      "id": "code-3",
      "language": "python",
      "description": "",
      "code": "# api_key_service.py\nimport secrets\nimport hashlib\nimport hmac\nfrom datetime import datetime, timezone\nfrom typing import Optional\n\nclass APIKeyService:\n    \"\"\"API Key 管理服务\"\"\"\n    \n    PREFIX = \"ak_live_\"     # 生产环境 Key 前缀\n    TEST_PREFIX = \"ak_test_\" # 测试环境 Key 前缀\n    \n    def generate_key(self, tenant_id: str, name: str,\n                     scopes: list[str], is_test: bool = False\n                     ) -> dict:\n        \"\"\"生成新的 API Key\"\"\"\n        # 生成随机密钥（32 字节）\n        raw_key = secrets.token_bytes(32)\n        key_str = secrets.token_urlsafe(32)\n        \n        prefix = self.TEST_PREFIX if is_test else self.PREFIX\n        api_key = f\"{prefix}{key_str}\"\n        \n        # 只存储哈希值，不存储明文\n        key_hash = self._hash_key(raw_key)\n        key_prefix = api_key[:12]  # 存储前缀用于识别\n        \n        # 存储到数据库\n        self.db.execute(\n            \"\"\"INSERT INTO api_keys \n               (tenant_id, name, key_hash, key_prefix, scopes, is_test)\n               VALUES (%s, %s, %s, %s, %s, %s)\"\"\",\n            (tenant_id, name, key_hash, key_prefix, scopes, is_test)\n        )\n        \n        # API Key 只在创建时显示一次\n        return {\n            \"api_key\": api_key,\n            \"key_id\": key_hash[:16],\n            \"name\": name,\n            \"scopes\": scopes,\n            \"is_test\": is_test,\n            \"created_at\": datetime.now(timezone.utc).isoformat()\n        }\n    \n    def verify_key(self, api_key: str) -> Optional[dict]:\n        \"\"\"验证 API Key\"\"\"\n        if not api_key:\n            return None\n        \n        # 提取前缀进行快速查找\n        key_prefix = api_key[:12]\n        \n        # 从数据库查找匹配的 Key\n        row = self.db.query(\n            \"SELECT * FROM api_keys WHERE key_prefix = %s AND is_revoked = FALSE\",\n            (key_prefix,)\n        )\n        \n        if not row:\n            return None\n        \n        # 验证完整密钥（constant-time comparison 防止时序攻击）\n        if not hmac.compare_digest(self._hash_key(api_key.encode()), row['key_hash']):\n            return None\n        \n        return {\n            \"tenant_id\": row['tenant_id'],\n            \"scopes\": row['scopes'],\n            \"is_test\": row['is_test']\n        }\n    \n    def _hash_key(self, key: bytes) -> str:\n        \"\"\"密钥哈希（使用 SHA-256）\"\"\"\n        return hashlib.sha256(key).hexdigest()",
      "section_ref": "39.2.3",
      "runnable": true,
      "dependencies": [
        "secrets",
        "hmac"
      ]
    },
    {
      "id": "code-4",
      "language": "mermaid",
      "description": "Agent 平台推荐使用 RBAC（基于角色）与 ABAC（基于属性）的混合授权模型：",
      "code": "graph TB\n    subgraph RBAC[\"RBAC - 基于角色\"]\n        Admin[管理员]\n        Developer[开发者]\n        User[普通用户]\n        Viewer[查看者]\n    end\n    \n    subgraph ABAC[\"ABAC - 基于属性\"]\n        Time[时间限制]\n        IP[IP 白名单]\n        Resource[资源类型]\n        Env[环境]\n    end\n    \n    subgraph Permissions[\"权限\"]\n        P1[创建会话]\n        P2[管理 Skill]\n        P3[查看统计]\n        P4[管理用户]\n        P5[执行工具]\n        P6[访问知识库]\n    end\n    \n    Admin --> P1 & P2 & P3 & P4 & P5 & P6\n    Developer --> P1 & P2 & P5 & P6\n    User --> P1 & P5 & P6\n    Viewer --> P3\n    \n    Time & IP & Resource & Env --> PolicyEngine[策略引擎]\n    PolicyEngine --> DenyOrAllow[允许/拒绝]",
      "section_ref": "39.3.1",
      "runnable": false,
      "dependencies": []
    },
    {
      "id": "code-5",
      "language": "python",
      "description": "",
      "code": "# authorization.py\nfrom dataclasses import dataclass\nfrom enum import Enum\nfrom typing import List, Optional, Callable\n\nclass Permission(Enum):\n    # 会话管理\n    SESSION_CREATE = \"session:create\"\n    SESSION_READ = \"session:read\"\n    SESSION_DELETE = \"session:delete\"\n    \n    # Agent 操作\n    AGENT_EXECUTE = \"agent:execute\"\n    AGENT_CONFIGURE = \"agent:configure\"\n    \n    # 工具管理\n    TOOL_EXECUTE = \"tool:execute\"\n    TOOL_MANAGE = \"tool:manage\"\n    \n    # 知识库\n    KB_READ = \"kb:read\"\n    KB_WRITE = \"kb:write\"\n    KB_DELETE = \"kb:delete\"\n    KB_MANAGE = \"kb:manage\"\n    \n    # 技能系统\n    SKILL_READ = \"skill:read\"\n    SKILL_WRITE = \"skill:write\"\n    SKILL_PUBLISH = \"skill:publish\"\n    \n    # 管理\n    USER_MANAGE = \"user:manage\"\n    ADMIN_PANEL = \"admin:panel\"\n    BILLING_VIEW = \"billing:view\"\n\n# 角色定义\nROLE_PERMISSIONS = {\n    \"admin\": [p for p in Permission],  # 所有权限\n    \"developer\": [\n        Permission.SESSION_CREATE, Permission.SESSION_READ,\n        Permission.AGENT_EXECUTE, Permission.AGENT_CONFIGURE,\n        Permission.TOOL_EXECUTE, Permission.TOOL_MANAGE,\n        Permission.KB_READ, Permission.KB_WRITE,\n        Permission.SKILL_READ, Permission.SKILL_WRITE,\n    ],\n    \"user\": [\n        Permission.SESSION_CREATE, Permission.SESSION_READ,\n        Permission.AGENT_EXECUTE,\n        Permission.TOOL_EXECUTE,\n        Permission.KB_READ,\n        Permission.SKILL_READ,\n    ],\n    \"viewer\": [\n        Permission.SESSION_READ,\n        Permission.KB_READ,\n        Permission.SKILL_READ,\n        Permission.BILLING_VIEW,\n    ],\n}\n\n@dataclass\nclass AccessContext:\n    \"\"\"访问上下文（ABAC 属性）\"\"\"\n    user_id: str\n    tenant_id: str\n    roles: List[str]\n    source_ip: str\n    user_agent: str\n    resource_type: str\n    resource_id: str\n    action: str\n    environment: str = \"production\"\n\nclass PolicyEngine:\n    \"\"\"混合 RBAC + ABAC 策略引擎\"\"\"\n    \n    def __init__(self):\n        self.attribute_policies: List[Callable] = []\n        self._register_default_policies()\n    \n    def check_permission(self, context: AccessContext,\n                         required_permission: Permission) -> bool:\n        \"\"\"检查是否具有权限\"\"\"\n        # 1. RBAC 检查\n        has_role = self._check_rbac(context.roles, required_permission)\n        if not has_role:\n            return False\n        \n        # 2. ABAC 属性检查（所有策略必须通过）\n        for policy in self.attribute_policies:\n            if not policy(context):\n                return False\n        \n        # 3. 资源级别检查（租户隔离）\n        if not self._check_resource_access(context):\n            return False\n        \n        return True\n    \n    def _check_rbac(self, roles: List[str],\n                    permission: Permission) -> bool:\n        \"\"\"RBAC 角色权限检查\"\"\"\n        for role in roles:\n            if permission in ROLE_PERMISSIONS.get(role, []):\n                return True\n        return False\n    \n    def _check_resource_access(self, context: AccessContext) -> bool:\n        \"\"\"资源级别的访问检查（确保租户隔离）\"\"\"\n        # 管理员可以访问所有资源\n        if \"admin\" in context.roles:\n            return True\n        \n        # 其他用户只能访问自己租户的资源\n        # 具体实现取决于资源类型\n        return True  # 简化示例\n    \n    def _register_default_policies(self):\n        \"\"\"注册默认的 ABAC 策略\"\"\"\n        \n        # IP 白名单策略（仅对管理操作）\n        def ip_whitelist_policy(ctx: AccessContext) -> bool:\n            if ctx.action in [\"admin:panel\", \"user:manage\"]:\n                return ctx.source_ip in self._get_admin_ip_whitelist()\n            return True\n        self.attribute_policies.append(ip_whitelist_policy)\n        \n        # 环境隔离策略\n        def environment_policy(ctx: AccessContext) -> bool:\n            if ctx.environment == \"production\":\n                # 生产环境要求更强的认证\n                return len(ctx.roles) > 0\n            return True\n        self.attribute_policies.append(environment_policy)\n    \n    def _get_admin_ip_whitelist(self) -> set:\n        \"\"\"获取管理员 IP 白名单\"\"\"\n        return {\"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\"}\n\n\n# 使用装饰器\ndef require_permission(permission: Permission):\n    \"\"\"权限检查装饰器\"\"\"\n    def decorator(func):\n        @wraps(func)\n        async def wrapper(*args, **kwargs):\n            # 从请求上下文中获取访问信息\n            request = kwargs.get('request')\n            auth_payload = request.state.auth_payload\n            \n            context = AccessContext(\n                user_id=auth_payload['sub'],\n                tenant_id=auth_payload.get('tenant_id', ''),\n                roles=auth_payload.get('roles', []),\n                source_ip=request.client.host,\n                user_agent=request.headers.get('user-agent', ''),\n                resource_type=kwargs.get('resource_type', ''),\n                resource_id=kwargs.get('resource_id', ''),\n                action=permission.value,\n            )\n            \n            policy = PolicyEngine()\n            if not policy.check_permission(context, permission):\n                raise HTTPException(\n                    status_code=403,\n                    detail=f\"Permission denied: {permission.value}\"\n                )\n            \n            return await func(*args, **kwargs)\n        return wrapper\n    return decorator",
      "section_ref": "39.3.2",
      "runnable": true,
      "dependencies": []
    },
    {
      "id": "code-6",
      "language": "python",
      "description": "",
      "code": "# input_validation.py\nimport re\nfrom typing import Optional\nfrom dataclasses import dataclass\nfrom pydantic import BaseModel, field_validator, Field\n\nclass ChatRequest(BaseModel):\n    \"\"\"聊天请求验证模型\"\"\"\n    session_id: Optional[str] = None\n    message: str = Field(..., min_length=1, max_length=32000)\n    agent_type: str = Field(default=\"chat\")\n    model: Optional[str] = None\n    temperature: float = Field(default=0.7, ge=0, le=2.0)\n    max_tokens: int = Field(default=4096, ge=1, le=128000)\n    \n    @field_validator('message')\n    @classmethod\n    def validate_message(cls, v: str) -> str:\n        \"\"\"验证并清洗用户输入\"\"\"\n        # 检查长度\n        if len(v) > 32000:\n            raise ValueError(\"Message too long (max 32000 characters)\")\n        \n        # 移除控制字符（保留换行和制表符）\n        cleaned = re.sub(r'[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]', '', v)\n        \n        return cleaned\n    \n    @field_validator('agent_type')\n    @classmethod\n    def validate_agent_type(cls, v: str) -> str:\n        allowed = {\"chat\", \"rag\", \"tool_call\", \"multi_agent\"}\n        if v not in allowed:\n            raise ValueError(f\"Invalid agent_type: {v}\")\n        return v\n    \n    @field_validator('model')\n    @classmethod\n    def validate_model(cls, v: Optional[str]) -> Optional[str]:\n        if v is None:\n            return v\n        allowed_models = {\n            \"gpt-4o\", \"gpt-4o-mini\",\n            \"claude-3-opus\", \"claude-3-sonnet\", \"claude-3-haiku\",\n        }\n        if v not in allowed_models:\n            raise ValueError(f\"Unsupported model: {v}\")\n        return v\n\nclass DocumentUploadRequest(BaseModel):\n    \"\"\"文档上传验证\"\"\"\n    title: str = Field(..., min_length=1, max_length=500)\n    knowledge_base_id: str\n    file_type: str\n    \n    @field_validator('file_type')\n    @classmethod\n    def validate_file_type(cls, v: str) -> str:\n        allowed = {\"pdf\", \"txt\", \"md\", \"docx\", \"csv\", \"json\"}\n        if v not in allowed:\n            raise ValueError(f\"Unsupported file type: {v}\")\n        return v",
      "section_ref": "39.4.1",
      "runnable": true,
      "dependencies": [
        "pydantic"
      ]
    },
    {
      "id": "code-7",
      "language": "python",
      "description": "",
      "code": "# security_rate_limiter.py\n\"\"\"安全维度的限流器 - 防止暴力破解和滥用\"\"\"\n\nclass SecurityRateLimiter:\n    \"\"\"安全限流器\"\"\"\n    \n    def __init__(self, redis_client):\n        self.redis = redis_client\n    \n    async def check_auth_attempts(self, identifier: str) -> bool:\n        \"\"\"检查认证尝试（防暴力破解）\"\"\"\n        key = f\"auth:attempts:{identifier}\"\n        \n        # 滑动窗口：5 分钟内最多 10 次失败\n        current = await self.redis.get(key)\n        if current and int(current) >= 10:\n            # 检查是否被锁定\n            lock_key = f\"auth:lock:{identifier}\"\n            if await self.redis.exists(lock_key):\n                ttl = await self.redis.ttl(lock_key)\n                raise SecurityError(\n                    f\"Account temporarily locked. \"\n                    f\"Try again in {ttl} seconds.\"\n                )\n        \n        return True\n    \n    async def record_auth_failure(self, identifier: str):\n        \"\"\"记录认证失败\"\"\"\n        key = f\"auth:attempts:{identifier}\"\n        count = await self.redis.incr(key)\n        \n        if count == 1:\n            await self.redis.expire(key, 300)  # 5 分钟窗口\n        \n        # 连续失败 10 次，锁定 15 分钟\n        if count >= 10:\n            lock_key = f\"auth:lock:{identifier}\"\n            await self.redis.setex(lock_key, 900, \"1\")\n    \n    async def check_content_injection(self, content: str,\n                                     session_id: str) -> bool:\n        \"\"\"检查可疑的 Prompt 注入行为\"\"\"\n        key = f\"injection:check:{session_id}\"\n        \n        # 同一会话中短时间内大量包含系统指令关键词\n        injection_patterns = [\n            r'ignore\\s+(previous|above|all)\\s+instructions',\n            r'you\\s+are\\s+now',\n            r'system\\s*prompt',\n            r'disregard',\n            r'pretend\\s+you\\s+are',\n            r'new\\s+instructions?',\n            r'forget\\s+(everything|all)',\n        ]\n        \n        suspicious_count = 0\n        for pattern in injection_patterns:\n            if re.search(pattern, content, re.IGNORECASE):\n                suspicious_count += 1\n        \n        if suspicious_count >= 3:\n            # 记录可疑行为\n            await self.redis.incr(key)\n            await self.redis.expire(key, 3600)\n            count = await self.redis.get(key)\n            \n            if int(count) >= 5:\n                raise SecurityError(\n                    \"Suspicious activity detected. \"\n                    \"Session has been flagged for review.\"\n                )\n        \n        return True",
      "section_ref": "39.4.2",
      "runnable": true,
      "dependencies": []
    },
    {
      "id": "code-8",
      "language": "text",
      "description": "",
      "code": "数据加密层次：\n┌────────────────────────────────────────┐\n│  传输中加密 (TLS 1.3)                  │ ← 客户端 ↔ 服务端\n├────────────────────────────────────────┤\n│  应用层加密 (AES-256-GCM)               │ ← 敏感字段\n├────────────────────────────────────────┤\n│  存储加密 (磁盘加密 / 数据库加密)        │ ← 数据库\n├────────────────────────────────────────┤\n│  密钥管理 (KMS / HashiCorp Vault)      │ ← 密钥生命周期\n└────────────────────────────────────────┘",
      "section_ref": "39.5.1",
      "runnable": false,
      "dependencies": []
    },
    {
      "id": "code-9",
      "language": "python",
      "description": "└────────────────────────────────────────┘",
      "code": "# encryption_service.py\nimport os\nimport base64\nfrom cryptography.hazmat.primitives.ciphers.aead import AESGCM\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.kdf.hkdf import HKDF\nfrom cryptography.hazmat.backends import default_backend\n\nclass EncryptionService:\n    \"\"\"数据加密服务\"\"\"\n    \n    def __init__(self, kms_key_id: str, kms_client):\n        self.kms_key_id = kms_key_id\n        self.kms = kms_client\n        self._local_cache = {}  # 数据密钥缓存\n    \n    def encrypt_field(self, plaintext: str, context: str = \"\") -> str:\n        \"\"\"加密单个字段\"\"\"\n        # 1. 获取或派生数据密钥\n        dek = self._get_or_derive_key(context)\n        \n        # 2. AES-256-GCM 加密\n        aesgcm = AESGCM(dek)\n        nonce = os.urandom(12)  # 96-bit nonce\n        ciphertext = aesgcm.encrypt(nonce, plaintext.encode(), None)\n        \n        # 3. 组合 nonce + ciphertext 并 Base64 编码\n        encrypted = nonce + ciphertext\n        return base64.b64encode(encrypted).decode()\n    \n    def decrypt_field(self, encrypted_b64: str, context: str = \"\") -> str:\n        \"\"\"解密单个字段\"\"\"\n        encrypted = base64.b64decode(encrypted_b64)\n        \n        # 提取 nonce (前12字节) 和密文\n        nonce = encrypted[:12]\n        ciphertext = encrypted[12:]\n        \n        # 解密\n        dek = self._get_or_derive_key(context)\n        aesgcm = AESGCM(dek)\n        plaintext = aesgcm.decrypt(nonce, ciphertext, None)\n        \n        return plaintext.decode()\n    \n    def _get_or_derive_key(self, context: str) -> bytes:\n        \"\"\"从 KMS 获取密钥或本地派生\"\"\"\n        if context in self._local_cache:\n            return self._local_cache[context]\n        \n        # 使用 HKDF 从主密钥派生特定上下文的数据密钥\n        master_key = self.kms.get_key(self.kms_key_id)\n        \n        hkdf = HKDF(\n            algorithm=hashes.SHA256(),\n            length=32,  # AES-256\n            salt=None,\n            info=context.encode(),\n            backend=default_backend()\n        )\n        \n        derived_key = hkdf.derive(master_key)\n        self._local_cache[context] = derived_key\n        return derived_key\n\n# 需要加密的敏感字段\nENCRYPTED_FIELDS = {\n    \"users\": [\"email\", \"phone\", \"display_name\"],\n    \"api_keys\": [\"key_hash\"],\n    \"tenants\": [\"config\"],\n    \"sessions\": [\"metadata\"],\n}\n\ndef encrypt_model_fields(model_data: dict, table: str,\n                         encryption: EncryptionService) -> dict:\n    \"\"\"加密模型中指定的字段\"\"\"\n    encrypted = model_data.copy()\n    fields = ENCRYPTED_FIELDS.get(table, [])\n    \n    for field in fields:\n        if field in encrypted and encrypted[field]:\n            encrypted[field] = encryption.encrypt_field(\n                str(encrypted[field]), \n                context=f\"{table}:{field}\"\n            )\n    \n    return encrypted",
      "section_ref": "39.5.1",
      "runnable": true,
      "dependencies": [
        "base64",
        "cryptography"
      ]
    },
    {
      "id": "code-10",
      "language": "nginx",
      "description": "",
      "code": "# nginx_tls.conf\nserver {\n    listen 443 ssl http2;\n    server_name api.agent-platform.com;\n    \n    # TLS 1.3 only\n    ssl_protocols TLSv1.3;\n    ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;\n    ssl_prefer_server_ciphers off;\n    \n    # 证书\n    ssl_certificate /etc/ssl/certs/agent-platform.pem;\n    ssl_certificate_key /etc/ssl/private/agent-platform.key;\n    \n    # OCSP Stapling\n    ssl_stapling on;\n    ssl_stapling_verify on;\n    resolver 8.8.8.8 8.8.4.4 valid=300s;\n    \n    # 安全头部\n    add_header Strict-Transport-Security \"max-age=63072000; includeSubDomains; preload\" always;\n    add_header X-Content-Type-Options \"nosniff\" always;\n    add_header X-Frame-Options \"DENY\" always;\n    add_header X-XSS-Protection \"1; mode=block\" always;\n    add_header Content-Security-Policy \"default-src 'none'; frame-ancestors 'none'\" always;\n    \n    # HSTS preload\n    add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n    \n    location / {\n        proxy_pass http://agent-gateway:8080;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}",
      "section_ref": "39.5.2",
      "runnable": false,
      "dependencies": []
    },
    {
      "id": "code-11",
      "language": "python",
      "description": "Prompt 注入是 Agent 系统最独特的安全威胁。防御需要多层策略：",
      "code": "# prompt_security.py\nimport re\nfrom typing import Optional\n\nclass PromptSecurityGuard:\n    \"\"\"Prompt 安全防护\"\"\"\n    \n    def __init__(self):\n        self.injection_patterns = self._compile_patterns()\n        self.output_filters = self._compile_output_filters()\n    \n    def sanitize_input(self, user_input: str) -> str:\n        \"\"\"清洗用户输入，降低注入风险\"\"\"\n        sanitized = user_input\n        \n        # 1. 移除可能触发指令解释的特殊标记\n        sanitized = re.sub(r'</?(system|assistant|user|instruction)>', \n                          '', sanitized, flags=re.IGNORECASE)\n        \n        # 2. 转义类似代码块的结构\n        # （防止用户通过代码块格式嵌入系统指令）\n        \n        # 3. 限制连续换行\n        sanitized = re.sub(r'\\n{4,}', '\\n\\n\\n', sanitized)\n        \n        return sanitized.strip()\n    \n    def detect_injection(self, user_input: str) -> dict:\n        \"\"\"检测可能的 Prompt 注入\"\"\"\n        risks = []\n        risk_score = 0\n        \n        for pattern_name, (pattern, severity) in self.injection_patterns.items():\n            if re.search(pattern, user_input, re.IGNORECASE):\n                risks.append({\n                    \"type\": pattern_name,\n                    \"severity\": severity,\n                    \"matched_pattern\": pattern\n                })\n                risk_score += severity\n        \n        return {\n            \"is_suspicious\": risk_score > 5,\n            \"risk_score\": risk_score,\n            \"risks\": risks,\n            \"recommendation\": self._get_recommendation(risk_score)\n        }\n    \n    def filter_output(self, agent_output: str,\n                      system_prompt_hash: str) -> str:\n        \"\"\"过滤 Agent 输出，防止信息泄露\"\"\"\n        filtered = agent_output\n        \n        # 1. 检查是否泄露了系统 Prompt\n        if self._detect_prompt_leak(filtered, system_prompt_hash):\n            filtered = \"[部分内容已被安全策略过滤]\"\n        \n        # 2. 过滤敏感信息模式\n        for pattern_name, pattern in self.output_filters.items():\n            if re.search(pattern, filtered):\n                filtered = re.sub(pattern, '[已过滤]', filtered)\n        \n        return filtered\n    \n    def _compile_patterns(self) -> dict:\n        \"\"\"编译注入检测模式\"\"\"\n        return {\n            \"role_impersonation\": (\n                r'(ignore|disregard|forget)\\s+(all\\s+)?(previous|above|prior)\\s+(instructions?|prompts?|rules?)',\n                3\n            ),\n            \"system_prompt_extraction\": (\n                r'(repeat|show|print|output|display)\\s+(the\\s+)?(system\\s+)?prompt',\n                4\n            ),\n            \"instruction_override\": (\n                r'(you\\s+are\\s+now|new\\s+(instructions?|rules?|role))\\s*[:]',\n                3\n            ),\n            \"tool_exploitation\": (\n                r'(execute|run|call|invoke)\\s+(this\\s+)?(command|script|code|tool)\\s*[:]',\n                2\n            ),\n            \"data_exfiltration\": (\n                r'(send|email|post|upload|transmit)\\s+(this|all|the|your)\\s+(data|info|messages?|logs?)',\n                4\n            ),\n        }\n    \n    def _compile_output_filters(self) -> dict:\n        \"\"\"编译输出过滤模式\"\"\"\n        return {\n            \"email\": r'\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b',\n            \"phone\": r'\\b1[3-9]\\d{9}\\b',\n            \"id_card\": r'\\b\\d{17}[\\dXx]\\b',\n            \"credit_card\": r'\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b',\n        }\n    \n    def _detect_prompt_leak(self, output: str,\n                           prompt_hash: str) -> bool:\n        \"\"\"检测是否泄露了系统 Prompt\"\"\"\n        # 简化实现：检查输出中是否包含系统 Prompt 的关键片段\n        # 实际中应使用更复杂的检测方法\n        return False\n    \n    def _get_recommendation(self, risk_score: int) -> str:\n        if risk_score <= 2:\n            return \"low_risk\"\n        elif risk_score <= 5:\n            return \"monitor\"\n        elif risk_score <= 10:\n            return \"warn_user\"\n        else:\n            return \"block_and_review\"",
      "section_ref": "39.6.1",
      "runnable": true,
      "dependencies": []
    },
    {
      "id": "code-12",
      "language": "python",
      "description": "Agent 调用工具时必须在安全的沙箱环境中执行：",
      "code": "# tool_sandbox.py\nimport subprocess\nimport tempfile\nimport os\nfrom typing import Optional\n\nclass ToolSandbox:\n    \"\"\"工具执行沙箱\"\"\"\n    \n    def __init__(self):\n        self.allowed_commands = self._load_allowed_commands()\n        self.resource_limits = {\n            \"max_cpu_seconds\": 30,\n            \"max_memory_mb\": 256,\n            \"max_output_bytes\": 1024 * 1024,  # 1MB\n            \"max_file_size_mb\": 10,\n            \"timeout_seconds\": 60,\n            \"network_allowed\": False,\n        }\n    \n    def execute_tool(self, tool_name: str, tool_input: dict,\n                     context: dict) -> dict:\n        \"\"\"在沙箱中执行工具\"\"\"\n        # 1. 验证工具权限\n        if not self._check_tool_permission(tool_name, context):\n            raise PermissionError(\n                f\"Tool '{tool_name}' not allowed for this context\"\n            )\n        \n        # 2. 验证输入\n        validated_input = self._validate_tool_input(tool_name, tool_input)\n        \n        # 3. 在沙箱中执行\n        result = self._run_in_sandbox(tool_name, validated_input)\n        \n        # 4. 过滤输出\n        filtered_output = self._filter_tool_output(result)\n        \n        return filtered_output\n    \n    def _run_in_sandbox(self, tool_name: str,\n                        tool_input: dict) -> dict:\n        \"\"\"在隔离环境中执行\"\"\"\n        # 使用 Docker 容器或 nsjail 作为沙箱\n        cmd = self._build_sandbox_command(tool_name, tool_input)\n        \n        try:\n            result = subprocess.run(\n                cmd,\n                capture_output=True,\n                text=True,\n                timeout=self.resource_limits[\"timeout_seconds\"],\n                # 安全限制\n                preexec_fn=self._apply_resource_limits,\n            )\n            \n            return {\n                \"exit_code\": result.returncode,\n                \"stdout\": result.stdout[:self.resource_limits[\"max_output_bytes\"]],\n                \"stderr\": result.stderr[:1024],  # 限制 stderr\n            }\n        except subprocess.TimeoutExpired:\n            return {\n                \"exit_code\": -1,\n                \"stdout\": \"\",\n                \"stderr\": \"Tool execution timed out\"\n            }\n    \n    def _build_sandbox_command(self, tool_name: str,\n                                tool_input: dict) -> list:\n        \"\"\"构建沙箱执行命令\"\"\"\n        # Docker 沙箱示例\n        return [\n            \"docker\", \"run\", \"--rm\",\n            \"--network=none\",  # 禁止网络\n            \"--memory=256m\",   # 内存限制\n            \"--cpus=1\",        # CPU 限制\n            \"--pids-limit=100\", # 进程数限制\n            \"--read-only\",     # 只读文件系统\n            f\"agent-tool-{tool_name}:latest\",\n            json.dumps(tool_input)\n        ]\n    \n    def _check_tool_permission(self, tool_name: str,\n                               context: dict) -> bool:\n        \"\"\"检查工具执行权限\"\"\"\n        user_roles = context.get(\"roles\", [])\n        tenant_tools = context.get(\"tenant_config\", {}).get(\"allowed_tools\", [])\n        \n        # 管理员可以使用所有工具\n        if \"admin\" in user_roles:\n            return True\n        \n        # 其他用户只能使用租户允许的工具\n        return tool_name in tenant_tools",
      "section_ref": "39.6.2",
      "runnable": true,
      "dependencies": [
        "subprocess",
        "tempfile"
      ]
    },
    {
      "id": "code-13",
      "language": "python",
      "description": "",
      "code": "# audit_service.py\nimport json\nimport time\nfrom datetime import datetime, timezone\nfrom typing import Optional\n\nclass AuditService:\n    \"\"\"审计日志服务\"\"\"\n    \n    # 需要审计的操作类型\n    AUDITED_ACTIONS = {\n        # 认证相关\n        \"auth.login\": \"用户登录\",\n        \"auth.logout\": \"用户登出\",\n        \"auth.password_change\": \"密码修改\",\n        \"auth.api_key_create\": \"API Key 创建\",\n        \"auth.api_key_revoke\": \"API Key 吊销\",\n        \n        # 数据访问\n        \"session.create\": \"创建会话\",\n        \"session.read\": \"查看会话\",\n        \"session.delete\": \"删除会话\",\n        \"kb.document_upload\": \"上传文档\",\n        \"kb.document_delete\": \"删除文档\",\n        \n        # 管理操作\n        \"admin.user_create\": \"创建用户\",\n        \"admin.user_delete\": \"删除用户\",\n        \"admin.role_change\": \"角色变更\",\n        \"admin.config_change\": \"配置变更\",\n        \n        # Agent 操作\n        \"agent.tool_execute\": \"工具执行\",\n        \"agent.skill_install\": \"技能安装\",\n        \"agent.prompt_update\": \"Prompt 更新\",\n    }\n    \n    def log(self, action: str, actor: dict, resource: dict,\n            result: str = \"success\", metadata: Optional[dict] = None):\n        \"\"\"记录审计日志\"\"\"\n        audit_entry = {\n            \"timestamp\": datetime.now(timezone.utc).isoformat(),\n            \"action\": action,\n            \"action_description\": self.AUDITED_ACTIONS.get(action, action),\n            \"actor\": {\n                \"user_id\": actor.get(\"user_id\"),\n                \"email\": actor.get(\"email\"),\n                \"tenant_id\": actor.get(\"tenant_id\"),\n                \"roles\": actor.get(\"roles\", []),\n                \"ip_address\": actor.get(\"ip_address\"),\n                \"user_agent\": actor.get(\"user_agent\"),\n            },\n            \"resource\": {\n                \"type\": resource.get(\"type\"),\n                \"id\": resource.get(\"id\"),\n                \"name\": resource.get(\"name\"),\n            },\n            \"result\": result,\n            \"metadata\": metadata or {},\n        }\n        \n        # 写入审计日志（不可变）\n        self._write_audit_log(audit_entry)\n    \n    def _write_audit_log(self, entry: dict):\n        \"\"\"写入审计日志（追加写入，不可修改）\"\"\"\n        # 1. 写入 PostgreSQL（主要存储）\n        self.db.execute(\n            \"\"\"INSERT INTO audit_log \n               (timestamp, action, actor, resource, result, metadata)\n               VALUES (%s, %s, %s, %s, %s, %s)\"\"\",\n            (entry[\"timestamp\"], entry[\"action\"],\n             json.dumps(entry[\"actor\"]),\n             json.dumps(entry[\"resource\"]),\n             entry[\"result\"],\n             json.dumps(entry[\"metadata\"]))\n        )\n        \n        # 2. 异步写入 Kafka（用于长期归档和分析）\n        self.kafka.produce(\n            topic=\"audit.log\",\n            value=json.dumps(entry)\n        )\n        \n        # 3. 关键操作实时告警\n        if self._is_critical_action(entry[\"action\"]):\n            self._send_security_alert(entry)\n\n# 审计日志查询 API\nclass AuditQueryService:\n    \"\"\"审计日志查询服务\"\"\"\n    \n    def query(self, filters: dict, page: int = 1,\n              page_size: int = 50) -> dict:\n        \"\"\"查询审计日志\"\"\"\n        query = \"\"\"\n            SELECT * FROM audit_log\n            WHERE 1=1\n        \"\"\"\n        params = []\n        \n        if filters.get(\"user_id\"):\n            query += \" AND actor->>'user_id' = %s\"\n            params.append(filters[\"user_id\"])\n        \n        if filters.get(\"action\"):\n            query += \" AND action = %s\"\n            params.append(filters[\"action\"])\n        \n        if filters.get(\"start_time\"):\n            query += \" AND timestamp >= %s\"\n            params.append(filters[\"start_time\"])\n        \n        if filters.get(\"end_time\"):\n            query += \" AND timestamp <= %s\"\n            params.append(filters[\"end_time\"])\n        \n        if filters.get(\"result\"):\n            query += \" AND result = %s\"\n            params.append(filters[\"result\"])\n        \n        query += \" ORDER BY timestamp DESC LIMIT %s OFFSET %s\"\n        params.extend([page_size, (page - 1) * page_size])\n        \n        rows = self.db.query(query, params)\n        return {\n            \"items\": rows,\n            \"page\": page,\n            \"page_size\": page_size,\n            \"total\": self._count_results(filters)\n        }",
      "section_ref": "39.7.1",
      "runnable": true,
      "dependencies": []
    },
    {
      "id": "code-14",
      "language": "mermaid",
      "description": "- 敏感数据不记录在日志中",
      "code": "graph TD\n    Detect[安全事件检测] --> Classify[事件分级]\n    Classify --> P0[P0 - 紧急<br/>数据泄露/服务入侵]\n    Classify --> P1[P1 - 严重<br/>异常访问/Prompt注入]\n    Classify --> P2[P2 - 一般<br/>可疑行为]\n    \n    P0 --> Contain[立即遏制<br/>隔离受影响服务]\n    Contain --> Notify[通知管理层<br/>+ 安全团队]\n    Notify --> Investigate[调查分析]\n    Investigate --> Remediate[修复漏洞]\n    Remediate --> Review[事后复盘]\n    \n    P1 --> Contain2[限制影响范围]\n    Contain2 --> Investigate\n    P2 --> Monitor[增强监控]\n    Monitor --> Investigate\n    \n    style P0 fill:#ff4444,color:#fff\n    style P1 fill:#ff8800\n    style P2 fill:#ffcc00",
      "section_ref": "39.8.2",
      "runnable": false,
      "dependencies": []
    }
  ],
  "tables": [
    {
      "headers": [
        "方案",
        "适用场景",
        "安全性",
        "复杂度",
        "令牌管理"
      ],
      "data": [
        [
          "Session + Cookie",
          "Web 应用",
          "中",
          "低",
          "服务端管理"
        ],
        [
          "JWT (RS256)",
          "API + Web",
          "高",
          "中",
          "无状态"
        ],
        [
          "OAuth 2.0",
          "第三方集成",
          "高",
          "高",
          "标准化"
        ],
        [
          "API Key",
          "服务间通信",
          "中",
          "低",
          "静态密钥"
        ],
        [
          "mTLS",
          "服务间通信",
          "极高",
          "高",
          "证书管理"
        ]
      ]
    },
    {
      "headers": [
        "合规领域",
        "要求",
        "实现措施"
      ],
      "data": [
        [
          "数据隐私 (GDPR/个人信息保护法)",
          "用户有权删除其数据",
          "数据删除 API + 自动清理"
        ],
        [
          "数据存储",
          "敏感数据加密存储",
          "AES-256-GCM 字段级加密"
        ],
        [
          "传输安全",
          "数据传输加密",
          "TLS 1.3 强制"
        ],
        [
          "访问控制",
          "最小权限原则",
          "RBAC + ABAC 混合模型"
        ],
        [
          "审计追踪",
          "所有操作可追溯",
          "完整审计日志"
        ],
        [
          "数据保留",
          "数据保留期限管理",
          "ILM 生命周期管理"
        ],
        [
          "AI 透明度",
          "AI 生成内容标识",
          "响应中标注\"AI 生成\""
        ],
        [
          "Prompt 安全",
          "防止 Prompt 注入",
          "多层安全防护"
        ]
      ]
    }
  ],
  "key_takeaways": [],
  "common_pitfalls": [],
  "related_chapters": [
    "ch11",
    "ch36"
  ]
}