Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 人工智能 / Artificial Intelligence

智能体工程 / Agent Engineering

1. Agent 工程体系全景 / Agent Engineering System Overview

2. Function Calling - 让 LLM 具备行动能力 / Function Calling for Giving LLMs the Ability to Act

3. Agent 框架演进 - 从裸 SDK 到 LangGraph / The Evolution of Agent Frameworks from Raw SDKs to LangGraph

4. RAG 基础 - 让 Agent 拥有"知识" / Retrieval-Augmented Generation Fundamentals for Agent Knowledge

5. 记忆管理 - Agent 的大脑 / Memory Management as the Brain of an Agent

6. Agent 工作流 - 从单步到复杂的执行编排 / Agent Workflows from Single Steps to Complex Orchestration

7. 多 Agent 系统 - 多个 Agent 协作 / Multi-Agent Systems and Agent Collaboration

8. RAG 进阶 - 企业级知识库实战 / Advanced RAG for Enterprise Knowledge Bases

9. 真实 Agent 应用场景 / Real-World AI Agent Applications

10. Structured Output - 让 LLM 输出可控的结构化数据 / Structured Output for Controllable, Machine-Readable LLM Responses

11. Tools Design Best Practices - AI Agent 工具设计最佳实践 / Tools Design Best Practices for AI Agents

12. Agent 架构模式 - 从单 Agent 到多 Agent 的工程范式 / Agent Architecture Patterns

13. Agent Modes — 编程 Agent 的交互模式设计 / Designing Interaction Modes for Coding Agents

14. Agent Workflow 编排:从循环到持久化执行的演进

15. Context Engineering - 从 Prompt 设计到上下文编排 / Context Engineering: From Prompt Design to Context Orchestration

16. Agent 缓存工程:从 KV Cache、Prompt Cache 到语义缓存 / Agent Caching Engineering

17. Harness Engineering, Skills, and Loop Engineering — 从信任模型到验证系统 / From Trusting Models to Verifying Systems

18. MCP 协议 - AI 工具的"USB 接口" / Model Context Protocol for AI Tool Integration

19. Agent 评估与测试 — 如何衡量一个"不可预测"的系统 / Agent Evaluation and Testing — How to Measure an "Unpredictable" System

20. 安全沙箱 - Agent 的安全边界 / Secure Sandboxes as Agent Safety Boundaries

21. 权限与门卫 - Agent 的安全控制中枢 / Permissions and Policy Gates for Agent Control

22. API Key 管理与安全 - Agent 的密钥生命周期的管理 / API Key Lifecycle Management and Security for Agents

23. 提示词注入防护 - Agent 的防御前沿 / Prompt Injection Defense for AI Agents

24. 可观测性与调试 - Agent 运行的透明度保障 / Observability and Debugging for Transparent Agent Operations

25. 模型路由 - 让正确的模型做正确的事 / Model Routing for Matching Models to Tasks

26. OpenClaw 设计深度分析 - 为什么它让人觉得"活"了 / OpenClaw Design Analysis and the Illusion of Liveliness

27. Claude Code 泄露源码深度分析 - 512,000 行代码揭示的生产级 Agent 架构 / Claude Code Source Analysis and Production Agent Architecture

28. LobeChat 设计深度分析 - 全栈 Agent Chat 应用工程实践 / LobeChat Design Analysis and Full-Stack Agent Chat Engineering

29. 编程 Agent 全面对比:从 Claude Code 到 Pi 的设计哲学 / Coding Agents Comparison: Design Philosophies from Claude Code to Pi

30. 领域 Agent 的确定性工具编译与延迟执行——从自然语言规格到单次 CAE 提交

31. Agent 工程学习指南 / An AI Agent Engineering Learning Guide

本页目录

API Key 管理与安全 - Agent 的密钥生命周期的管理 / API Key Lifecycle Management and Security for Agents ​

📅 创建时间:2026-05-08 🏷️ 标签:#APIKey #SecretsManagement #密钥轮换 #环境变量 #安全最佳实践 📚 前置知识:[[10-权限与门卫]]


📋 本章目标 ​

  • 理解 Agent 中 API Key 管理的特殊挑战
  • 掌握密钥注入、环境变量隔离、密钥轮换的方法
  • 理解密钥在沙箱和权限系统中的配合使用
  • 掌握生产环境的密钥安全策略
  • 理解密钥泄露的检测和响应

第1部分:Agent 中密钥管理的特殊挑战 ​

1.1 为什么 Agent 让密钥管理更复杂? ​

┌─────────────────────────────────────────────────────────────┐
│                    Agent 场景下的密钥风险                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  挑战1:Agent 可能"无意泄露"密钥                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Agent 读取了 .env 文件                               │   │
│  │ 然后在解释任务时把整个文件内容发给了 LLM             │   │
│  │ LLM 的 API 请求日志 → 密钥出现在日志中             │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  挑战2:Agent 可能在输出中暴露密钥                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Agent 执行了 curl https://api.example.com            │   │
│  │ 命令中包含 --header "Authorization: Bearer sk-xxx"  │   │
│  │ 这个命令被记录到了 Agent 的执行日志中                 │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  挑战3:Agent 可能把密钥当作普通内容处理                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Agent 分析日志时说:"这个请求使用了 sk-xxx 密钥"    │   │
│  │ 把密钥明文写进了摘要或报告                            │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  挑战4:密钥需要注入沙箱但又要隔离                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Agent 在 Docker 沙箱中运行                           │   │
│  │ 但需要访问宿主机上的密钥                              │   │
│  │ 直接挂载 → 沙箱外泄                                  │   │
│  │ 不挂载 → Agent 无法使用                               │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

1.2 密钥类型与风险分级 ​

┌─────────────────────────────────────────────────────────────┐
│                    Agent 中的密钥类型                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  高风险(必须严格保护)                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ LLM API Keys(OpenAI / Anthropic / Google)           │   │
│  │ 数据库密码                                            │   │
│  │ 云服务凭证(AWS / GCP / Azure)                      │   │
│  │ SSH 私钥                                             │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  中风险(需要审计跟踪)                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ GitHub Token                                          │   │
│  │ Slack / Discord Bot Token                              │   │
│  │ 第三方 API Key                                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  低风险(可配置但需最小权限)                               │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 搜索引擎 API                                           │   │
│  │ 地图 API                                               │   │
│  │ 天气 API                                               │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

第2部分:安全存储方案 ​

2.1 密钥存储层次 ​

┌─────────────────────────────────────────────────────────────┐
│                    密钥存储的五个层次                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  层次1:环境变量(基础)                                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ .env 文件 → 启动时注入到环境变量                      │   │
│  │ 环境变量 → 进程内存                                   │   │
│  │ 优点:简单                                           │   │
│  │ 缺点:ps aux 可泄露 /proc/environ 可读               │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  层次2:密钥管理服务(生产推荐)                            │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ AWS Secrets Manager / GCP Secret Manager / HashiCorp Vault │   │
│  │ Agent 在运行时按需获取                                 │   │
│  │ 优点:集中管理、审计、轮换                            │   │
│  │ 缺点:需要网络访问、有延迟                             │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  层次3:本地加密存储(轻量方案)                            │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 系统密钥环(macOS Keychain / Linux keyctl)          │   │
│  │ 操作系统级保护                                        │   │
│  │ 优点:无需网络、OS 级安全                             │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

2.2 .env 文件管理 ​

┌─────────────────────────────────────────────────────────────┐
│                    .env 文件管理策略                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  禁止行为:                                                 │
│  ❌ 将 .env 提交到 Git                                    │
│  ❌ 在代码中硬编码密钥                                     │
│  ❌ 把 .env 路径作为日志内容输出                           │
│  ❌ 在错误消息中包含密钥值                                 │
│                                                             │
│  正确做法:                                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ # .env.local(不上 Git)                             │   │
│  │ OPENAI_API_KEY=sk-xxx                               │   │
│  │ ANTHROPIC_API_KEY=sk-ant-xxx                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ # .env.example(必须提交,作为模板)                  │   │
│  │ OPENAI_API_KEY=  ← 空值,标注需要的值格式            │   │
│  │ ANTHROPIC_API_KEY=                                   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ # .gitignore                                         │   │
│  │ .env                                                 │   │
│  │ .env.local                                           │   │
│  │ .env.*.local                                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

2.3 密钥注入到沙箱 ​

python
import os
from pathlib import Path
import docker

class SecureKeyInjector:
    """安全地将密钥注入到 Agent 沙箱"""

    # 只允许注入这些密钥(白名单)
    ALLOWED_KEYS = {
        "OPENAI_API_KEY",
        "ANTHROPIC_API_KEY",
        "GITHUB_TOKEN",
        "SEARCH_API_KEY",
    }

    def inject_to_docker(self, container: docker.models.containers.Container):
        """安全注入环境变量到 Docker 容器"""
        env_to_inject = {}

        for key in self.ALLOWED_KEYS:
            value = os.environ.get(key)
            if value:
                # 检查值是否为空或 placeholder
                if value and not value.startswith("${") and "YOUR_" not in value:
                    env_to_inject[key] = value

        if env_to_inject:
            container.exec_run(
                f"env {' '.join(f'{k}={v}' for k, v in env_to_inject.items())}",
                workdir="/"
            )

    def inject_to_bwrap(self, allowed_keys: list[str] = None) -> list[str]:
        """为 bwrap 生成安全的环境变量参数"""
        keys = allowed_keys or list(self.ALLOWED_KEYS)
        bwrap_args = []

        for key in keys:
            value = os.environ.get(key)
            if value and not value.startswith("${"):
                # 通过 --setenv 注入(不会出现在 ps aux 中)
                bwrap_args.extend(["--setenv", key, value])

        return bwrap_args

    def create_readonly_env_file(self, output_path: str, allowed_keys: list[str] = None):
        """创建只读的 env 文件用于挂载"""
        keys = allowed_keys or list(self.ALLOWED_KEYS)
        lines = []

        for key in keys:
            value = os.environ.get(key, "")
            if value and not value.startswith("${"):
                lines.append(f"{key}={value}")

        env_content = "\n".join(lines)
        env_path = Path(output_path)
        env_path.write_text(env_content)
        env_path.chmod(0o400)  # 只读,只有所有者可读
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

第3部分:防止密钥泄露 ​

3.1 审计日志脱敏 ​

python
import re
import logging
from typing import Any

class SecretsObfuscator:
    """敏感信息脱敏器"""

    PATTERNS = {
        "openai_key": r"sk-[A-Za-z0-9_-]{20,}",
        "anthropic_key": r"sk-ant-[A-Za-z0-9_-]{20,}",
        "github_token": r"(ghp_|gho_|ghu_|ghs_|ghr_)[A-Za-z0-9_]{36,}",
        "aws_key": r"(AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16}",
        "generic_bearer": r"Bearer [A-Za-z0-9_.-]{20,}",
        "generic_api_key": r"['\"]?[a-zA-Z_]+[a-zA-Z0-9_]*['\"]?:\s*['\"]?[A-Za-z0-9_/-]{20,}['\"]?",
    }

    @classmethod
    def mask(cls, text: str, show_prefix: int = 4) -> str:
        """脱敏文本,显示前缀"""
        result = text

        for label, pattern in cls.PATTERNS.items():
            def replace(match):
                value = match.group(0)
                prefix = value[:show_prefix]
                suffix = "*" * (len(value) - show_prefix)
                return f"{prefix}{suffix} [REDACTED:{label}]"

            result = re.sub(pattern, replace, result, flags=re.IGNORECASE)

        return result

    @classmethod
    def check_for_secrets(cls, text: str) -> list[str]:
        """检测文本中是否包含密钥"""
        found = []
        for label, pattern in cls.PATTERNS.items():
            if re.search(pattern, text, re.IGNORECASE):
                found.append(label)
        return found


class SafeLogger:
    """安全的日志记录器"""

    def __init__(self, logger: logging.Logger):
        self.logger = logger

    def log(self, level: int, message: str, **kwargs: Any):
        """日志时自动脱敏"""
        # 脱敏所有参数
        safe_kwargs = {}
        for k, v in kwargs.items():
            if isinstance(v, str):
                safe_kwargs[k] = SecretsObfuscator.mask(v)
            else:
                safe_kwargs[k] = v

        self.logger.log(level, SecretsObfuscator.mask(message), **safe_kwargs)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

3.2 输出过滤器 ​

python
class AgentOutputFilter:
    """Agent 输出过滤器,防止密钥泄露"""

    def __init__(self):
        self.obfuscator = SecretsObfuscator()

    def filter_output(self, output: str, context: dict) -> str:
        """过滤 Agent 输出中的敏感信息"""
        # 1. 脱敏处理
        filtered = self.obfuscator.mask(output)

        # 2. 检查是否无意中暴露了配置
        if self._contains_exposed_config(output):
            # 替换为提示
            filtered = filtered.replace(
                self._extract_exposed_line(output),
                "# [配置内容已脱敏,请检查实际值]"
            )

        return filtered

    def filter_command(self, command: str) -> str:
        """过滤 bash 命令中的密钥"""
        # curl -H "Authorization: Bearer sk-xxx"
        command = re.sub(
            r'(-H\s+["\']Authorization:\s*)Bearer\s+[A-Za-z0-9_.-]+',
            r'\1Bearer [REDACTED]',
            command,
            flags=re.IGNORECASE
        )

        # export KEY=value
        command = re.sub(
            r'(export\s+\w+\s*=\s*)[^\s]+',
            r'\1[REDACTED]',
            command
        )

        return command

    def _contains_exposed_config(self, text: str) -> bool:
        """检查是否包含暴露的配置"""
        patterns = [
            r"api_key\s*=\s*['\"][A-Za-z0-9_-]{20,}['\"]",
            r"token\s*=\s*['\"][A-Za-z0-9_]{20,}['\"]",
            r"secret\s*=\s*['\"][A-Za-z0-9_]{20,}['\"]",
        ]
        return any(re.search(p, text) for p in patterns)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

第4部分:密钥轮换与最小权限 ​

4.1 密钥轮换策略 ​

┌─────────────────────────────────────────────────────────────┐
│                    密钥轮换策略                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  轮换触发条件:                                            │
│  1. 定期轮换(建议每 90 天)                               │
│  2. 密钥泄露事件后                                         │
│  3. 人员变动(离职/转岗)                                  │
│  4. 疑似被滥用的迹象                                        │
│                                                             │
│  轮换流程:                                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 1. 生成新密钥                                       │   │
│  │ 2. 部署到密钥管理器(不直接替换旧密钥)              │   │
│  │ 3. 观察期(1-2 周),确保旧密钥不被使用              │   │
│  │ 4. 旧密钥标记为"待废弃"                             │   │
│  │ 5. 确认所有系统已切换到新密钥                        │   │
│  │ 6. 旧密钥正式作废                                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

4.2 最小权限原则 ​

python
# GitHub Token 的最小权限配置
MINIMAL_GITHUB_TOKEN_SCOPES = {
    # 只读访问(分析任务)
    "只读分析": ["repo:read", "read:user", "read:org"],

    # 读写访问(代码修改)
    "代码修改": [
        "repo",  # 完全访问公开仓库
        # 不需要 repo:wite + admin,因为 Agent 不应该管理仓库设置
    ],

    # PR 评论(审核任务)
    "PR 审核": ["repo:read", "pull_requests:write", "issues:read"],

    # 发布(发布任务)
    "发布": ["repo", "packages:write"],
}

# AWS IAM 最小权限示例
MINIMAL_AWS_POLICY = {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::agent-workspace/*",  # 只在工作区桶
                "arn:aws:s3:::agent-workspace"       # 列出权限
            ]
        },
        {
            "Effect": "Deny",
            "NotAction": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::*"  # 禁止操作其他桶
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

第5部分:OpenClaw 的密钥管理 ​

┌─────────────────────────────────────────────────────────────┐
│                    OpenClaw 凭证存储                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  凭证存储位置:                                             │
│  ~/.openclaw/credentials/                                   │
│                                                             │
│  存储格式:                                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 每个 channel 的凭证独立存储                          │   │
│  │ whatsapp-credentials.json.enc                         │   │
│  │ telegram-bot-token.json.enc                           │   │
│  │ github-oauth.json.enc                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  加密方式:                                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 文件使用 agent 启动时的会话密钥加密                   │   │
│  │ 密钥不持久化在磁盘                                   │   │
│  │ 服务重启 → 需要重新认证                              │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  安全写入模式:                                            │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 先写临时文件 → 验证 JSON 有效 → 原子替换旧文件        │   │
│  │ 如果写入失败,不覆盖已有的正确凭证                   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

第6部分:密钥泄露检测与响应 ​

6.1 泄露检测 ​

python
import time
from collections import defaultdict

class SecretLeakDetector:
    """检测 Agent 操作中的密钥泄露"""

    def __init__(self):
        self.alert_threshold = 3  # 同一密钥出现 3 次触发告警
        self.seen = defaultdict(list)

    def monitor(self, event_type: str, content: str, context: dict):
        """监控事件并检测泄露"""
        found = SecretsObfuscator.check_for_secrets(content)

        for secret_type in found:
            self.seen[secret_type].append({
                "time": time.time(),
                "event": event_type,
                "context": context.get("source", "unknown")
            })

            if len(self.seen[secret_type]) >= self.alert_threshold:
                self._send_alert(secret_type, self.seen[secret_type])

    def _send_alert(self, secret_type: str, events: list):
        """发送泄露告警"""
        # 应该接入告警系统(Slack / PagerDuty / 邮件)
        print(f"[CRITICAL] 检测到可能的密钥泄露:{secret_type}")
        print(f"出现次数:{len(events)}")
        for e in events[-3:]:
            print(f"  - {e['context']} @ {time.ctime(e['time'])}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

6.2 泄露响应流程 ​

┌─────────────────────────────────────────────────────────────┐
│                    密钥泄露响应流程                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Step 1: 立即行动(1小时内)                               │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 撤销/轮换泄露的密钥                               │   │
│  │ • 确认泄露范围(哪些系统受影响)                    │   │
│  │ • 启动审计日志分析                                  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Step 2: 影响评估(24小时内)                               │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 密钥被访问了多少次?                              │   │
│  │ • 有没有被第三方使用?                              │   │
│  │ • 数据是否已泄露?                                  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Step 3: 修复措施                                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 加强 Agent 的密钥隔离                              │   │
│  │ • 添加输出过滤                                      │   │
│  │ • 更新检测规则                                      │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Step 4: 复盘改进                                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 分析根本原因                                      │   │
│  │ • 更新安全流程                                      │   │
│  │ • 培训团队                                          │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

核心总结 ​

总结1:密钥管理原则 ​

不暴露:密钥永远不出现在日志、输出、错误消息中
不硬编码:使用环境变量或密钥管理器
最小权限:只授予完成任务所需的最小范围
定期轮换:建立自动化的轮换机制
1
2
3
4

总结2:安全注入优先级 ​

生产环境:密钥管理服务(AWS Secrets Manager / Vault)
中等规模:系统密钥环(macOS Keychain / keyctl)
快速原型:加密 .env + 只读挂载
1
2
3

总结3:泄露防护三道关 ​

输入过滤 → Agent 无法读取敏感路径的密钥
执行过滤 → 命令和输出中的密钥被脱敏
审计监控 → 密钥异常访问触发告警
1
2
3

章节测试 ​

测试1:.env 安全 ​

以下哪个做法是正确的? A. 把 .env 文件提交到 Git 作为模板 B. .env 文件中写入占位符如 OPENAI_API_KEY=${OPENAI_API_KEY} C. 在日志中使用 logger.info(f"API Key: {api_key}") D. 把 .env 路径记录在错误消息中

测试2:脱敏 ​

如果密钥是 sk-ant-abc123xyz456789,显示前缀 4 位后,脱敏结果是什么?

测试3:存储层次 ​

生产环境应该使用哪种密钥存储方案?

测试4:最小权限 ​

Agent 只需要读取 GitHub 仓库内容,不需要写入,应该授予哪些权限? A. repo(完全仓库访问) B. repo:read(只读) C. admin:repo_hook(管理 Webhook) D. read:user(读取用户信息)

测试5:OpenClaw 凭证 ​

OpenClaw 的凭证文件为什么使用会话密钥加密而不是持久密钥?


参考答案 ​

测试1答案 ​

答案:B

解析:A 危险(.env 不应提交到 Git);B 正确(使用占位符作为模板);C 危险(日志中暴露密钥);D 危险(路径也是敏感信息)。


测试2答案 ​

答案:sk-an**** [REDACTED:anthropic_key]

解析:显示前缀 4 位 sk-an,后面用 * 替代,加上脱敏标记。


测试3答案 ​

答案:AWS Secrets Manager / GCP Secret Manager / HashiCorp Vault 等专用密钥管理服务。这些服务提供集中管理、审计日志、自动轮换和细粒度访问控制。


测试4答案 ​

答案:B(repo:read)和 D(read:user)

解析:只读任务应只授予 repo:read 和必要的 read:user,不应授予 repo(包含写入权限)或 admin:repo_hook。


测试5答案 ​

答案:会话密钥不持久化在磁盘,Agent 重启后需要重新认证。这意味着即使攻击者获取了加密的凭证文件,也无法解密(除非同时获取了会话密钥),提供了额外的安全层。


相关笔记 ​

  • [[10-权限与门卫]] - 权限系统与密钥的配合
  • [[09-安全沙箱]] - 沙箱中的密钥隔离
  • [[12-提示词注入防护]] - 提示词注入可能用于窃取密钥

下一步学习 ​

  • [ ] 阅读 21 - 提示词注入防护

学习状态:🟡 开始学习

最后更新于:

Pager
上一篇21. 权限与门卫 - Agent 的安全控制中枢 / Permissions and Policy Gates for Agent Control
下一篇23. 提示词注入防护 - Agent 的防御前沿 / Prompt Injection Defense for AI Agents

持续记录,持续成长

Copyright © Tidenflow