Agent 身份凭证配置
身份凭证是 Agent 与后端服务、签名验证、加密通信和访问控制的基石。本章围绕 API 密钥、证书路径、环境变量注入 和 密钥轮换策略 四个核心维度展开,覆盖从原理到生产部署的全链路实现。
4.1 凭证类型与作用域
| 凭证类型 | 典型用途 | 风险等级 | 配置位置 |
|---|---|---|---|
| API 密钥 | 请求签名、速率限制、身份识别 | 高 | 配置文件 / 环境变量 |
| X.509 证书 | mTLS 双向验证、代码签名 | 极高 | 文件系统 / 密钥管理服务 |
| 环境变量 | 运行时注入敏感参数 | 中 | Shell / 容器 / 编排平台 |
| 临时令牌(轮换产物) | 短期鉴权、最小权限 | 低(临时) | 内存 / 安全 Token 服务 |
4.2 原理:凭证生命周期
任何凭证都经历 生成 → 分发 → 注入 → 验证 → 使用 → 轮换 → 撤销 七个阶段。Agent 必须在启动时加载有效凭证,在运行时监听轮换信号,并在凭证失效前完成无缝切换。
- API 密钥:对称或非对称密钥对,通常以 Base64 编码存储。
- 证书:包含公钥、签发者、有效期,由内部 CA 签发。
- 环境变量:通过操作系统的
environ或容器编排器的 Secret 机制注入。 - 轮换:定期刷新凭证以降低泄露影响,需要新旧凭证并行窗口。
4.3 实现流程
- 设计凭证存储模型:决定使用文件系统、Vault 或云 KMS。
- 编写 Agent 配置模板:支持从环境变量、文件、KMS 读取。
- 实现热加载器:监听凭证文件变化或轮换信号。
- 配置轮换策略:定义轮换周期(如 24h)、Grace Period(如 1h)、失败回退机制。
- 验证与监控:在沙盒环境执行身份挑战测试,输出日志。
4.4 环境变量注入示例
Shell 启动脚本(适用于 Docker / Systemd)
export AGENT_API_KEY="sk-prod-a1b2c3..."
export AGENT_CERT_PATH="/etc/agent/certs/tls.crt"
export AGENT_KEY_PATH="/etc/agent/certs/tls.key"
./agent --config /etc/agent/config.yaml
Kubernetes Secret 注入(使用 environmentFrom)
apiVersion: v1
kind: Pod
metadata:
name: agent-pod
spec:
containers:
- name: agent
image: agent:v2.1
envFrom:
- secretRef:
name: agent-credentials
env:
- name: AGENT_CERT_PATH
value: "/secrets/cert.pem"
Python Agent 读取环境变量
import os
api_key = os.environ.get("AGENT_API_KEY")
cert_path = os.environ.get("AGENT_CERT_PATH")
if not api_key:
raise RuntimeError("Missing AGENT_API_KEY")
print(f"Loaded API key (len={len(api_key)})")
4.5 证书路径配置策略
| 配置方式 | 优点 | 缺点 |
|---|---|---|
| 硬编码路径 | 简单直观 | 不灵活,难以迁移 |
| 环境变量驱动 | 可跨环境覆盖 | 需管理额外变量 |
| 自动发现目录 | 支持热替换 | 需轮询文件系统 |
| KMS 直接加载 | 最高安全 | 增加网络延迟 |
最佳实践:生产环境优先使用环境变量 + 文件系统监听的组合,兼顾安全与灵活性。证书以 PEM 格式存入固定目录,Agent 启动时校验权限和有效期。
4.6 密钥轮换策略实现
轮换策略的核心是 不中断服务。Agent 应维护两个凭证槽:主凭证(生效中)和 次凭证(即将启用)。当主凭证到达轮换触发条件时,Agent 切换次凭证为主凭证,并异步请求新的次凭证。
轮换触发信号示例(SIGHUP / 文件变化)
# systemd unit 信号触发
ExecReload=/bin/kill -HUP $MAINPID
# agent 内部信号处理
import signal, os
def rotate_credentials(signum, frame):
load_next_credentials()
print("Credential rotation triggered by SIGHUP")
signal.signal(signal.SIGHUP, rotate_credentials)
自动轮换调度示例(基于时间窗口)
import time
ROTATION_INTERVAL = 86400 # 24h
GRACE_PERIOD = 3600 # 1h overla
next_rotation = time.time() + ROTATION_INTERVAL
while True:
if time.time() >= next_rotation:
rotate_credentials()
next_rotation = time.time() + ROTATION_INTERVAL
time.sleep(60)
4.7 调试与验证
- 检查环境变量是否注入:
echo $AGENT_API_KEY(仅开发环境) - 验证证书有效性:
openssl x509 -in /etc/agent/certs/tls.crt -noout -dates
openssl verify -CAfile ca.pem /etc/agent/certs/tls.crt
- API 密钥测试请求:
curl -H "Authorization: Bearer $AGENT_API_KEY" https://agent-api.internal/health
4.8 常见错误与解决方案
| 错误现象 | 可能原因 | 解决方法 |
|---|---|---|
| 启动失败:凭证未找到 | 环境变量名拼写错误 | 使用 env | grep AGENT 检查 |
| 证书格式错误 | PEM 首尾标记缺失 | 检查 -----BEGIN CERTIFICATE----- |
| 轮换后请求被拒 | 新旧凭证未共存窗口 | 增大 Grace Period 或实现双槽切换 |
| 权限不足 | 证书文件属主非 Agent 用户 | chmod 600 并 chown Agent 用户 |
警告:绝不在日志或终端明文打印完整 API 密钥。可使用 打印前 6 位 + "****" 或仅在调式模式输出哈希值。
4.9 性能与稳定性优化
- 凭证缓存:使用 LRU 缓存短期令牌,减少 KMS 调用。
- 异步轮换:在主线程外执行网络请求,避免阻塞请求处理。
- 熔断机制:如果轮换失败超过三次,回退到旧凭证并发出告警。
- 连接池共享:证书路径对应的 TLS 连接应使用连接池,避免每次握手重新加载证书。
- 热加载隔离:使用独立 goroutine / 线程处理文件变化事件,防止竞争条件。
4.10 凭证配置与轮换流程
4.11 生产部署检查清单
- 所有凭证文件权限为
600,属主为 Agent 专用用户。 - 环境变量中的密钥不在日志、进程列表可见。
- 证书有效期监控:每日检查过期告警。
- 轮换策略已配置 Grace Period,且新旧凭证至少并行 5 分钟。
- 已为
SIGHUP信号注册处理函数,支持手动触发轮换。 - 集成 APM 监控轮换耗时、失败次数。