跳转至

密钥管理规范

最后更新:2026-05-16(TFRM-118:VictoriaMetrics 拆除,remote_write 鉴权改为 OTLP Bearer)

本文档描述 TFRSManager 生产环境的密钥管理体系,包括 Infisical 平台、Machine Identity 认证、以及计费链路 OTLP Receiver 鉴权。

一、Infisical 密钥管理平台

1.1 部署信息

访问地址 https://secret.turingfocus.cn
部署方式 自托管 Docker Compose(/opt/infisical-infra/
容器 infisical + postgres:16-alpine + redis:7-alpine
备份 crontab 每日 03:00 执行 PostgreSQL dump,保留 30 天

1.2 项目与环境

Infisical 中按以下项目组织密钥:

项目 说明 环境
tfrs-manager 后端服务配置 Development / Staging / Production
tfrs-portals 前端配置 Development / Staging / Production
tfrs-k8s-platform K8s 集群配置 Production
tfrs-shared 共享配置 Production
infisical-infra Infisical 自身配置 Production

1.3 tfrs-manager 密钥目录结构

/                       → 顶层通用配置(GIN_MODE, LOG_LEVEL 等)
├── auth/               → JWT_SECRET
├── cos/                → 腾讯云 COS 凭证
├── database/           → PostgreSQL 连接信息
├── feishu/             → 飞书集成
├── k8s/                → K8s 集群配置
├── otlp/               → OTLP 计费链路 Bearer token(按 {cluster_id} 分目录,TFRM-119)
├── observability/      → OpenTelemetry 配置
├── payment/            → 支付宝/微信支付凭证
├── redis/              → Redis 连接信息
├── sms/                → 腾讯云短信
└── smtp/               → 邮件服务

二、Machine Identity(服务端认证)

2.1 概念

Machine Identity 是 Infisical 提供的非人类身份认证机制,用于让服务器/CI 以编程方式访问密钥。

2.2 当前 Identity

名称 ID 认证方式 项目权限 用途
cvm-prod-tfrs-manager 756c6d22-228c-4145-bed6-ec6473ccd1c4 Universal Auth tfrs-manager (Viewer) prod 服务器运行时

2.3 凭证存放

Machine Identity 的 Client ID / Client Secret 存放在 .env.prod 中:

INFISICAL_CLIENT_ID=634f5fde-...
INFISICAL_CLIENT_SECRET=86ee80a1...
INFISICAL_PROJECT_ID=8a9fd5ba-...
INFISICAL_ENVIRONMENT=prod

.env.prod 由 CNB CI/CD 流水线从密钥仓库文件 tfrsmanager_env.prod.yml 生成,通过 SSH 传输到服务器 /opt/tfrs/.env.prod

2.4 API 调用方式

由于 prod 服务器无法直接从 GitHub 下载 Infisical CLI(网络限制),脚本通过 HTTP API 直接调用自托管 Infisical:

# Step 1: 获取 Access Token
curl -sf https://secret.turingfocus.cn/api/v1/auth/universal-auth/login \
  -X POST -H "Content-Type: application/json" \
  -d '{"clientId":"...","clientSecret":"..."}'
# 返回 { "accessToken": "eyJ..." }

# Step 2: 读取密钥(示例:镜像仓库密码)
curl -sf https://secret.turingfocus.cn/api/v3/secrets/raw/CNB_REGISTRY_PASSWORD \
  -H "Authorization: Bearer <token>" \
  -G --data-urlencode "workspaceId=..." \
     --data-urlencode "environment=prod" \
     --data-urlencode "secretPath=/registry/"
# 返回 { "secret": { "secretValue": "..." } }

2.5 创建新 Machine Identity

如需为其他服务器或 CI 环境创建新的 Machine Identity:

  1. 登录 https://secret.turingfocus.cn
  2. Organization → Access Control → Machine Identities → Create
  3. 命名规则:{环境}-{服务器}-{项目}(如 cvm-staging-tfrs-manager
  4. 添加 Universal Auth 认证方式
  5. 在项目中授权,角色设为 Viewer(只读,最小权限原则)
  6. 创建 Client Secret 并妥善保存(创建后仅显示一次)

三、OTLP 计费链路鉴权(TFRM-119)

VictoriaMetrics 已于 TFRM-118 拆除, 原 Nginx Basic Auth + REMOTE_WRITE_PASSWORD 鉴权随之移除。计费 of-record 链路改由 OTLP Receiver 承载,鉴权方式由 Basic Auth 改为 Bearer Token

3.1 架构

K8s 集群内 ns 共享 StatefulSet OTel Collector 经公网 OTLP/HTTP 单一 /v1/logs 推送计费事件日志到管理平面 OTLP Receiver,使用 Bearer Token 鉴权。

ns 共享 StatefulSet OTel Collector
    │ OTLP/HTTP /v1/logs (HTTPS + Authorization: Bearer <token>)
┌──────────────────────────────────────────────────────┐
│ Nginx (metrics{,-staging,-beta}.turingfocus.cn:443)      │
│   └─ proxy_pass → 127.0.0.1:4318 (Receiver 仅监听本地) │
└─────────────────┬────────────────────────────────────┘
          ┌───────▼────────────────────────────────┐
          │ OTLP Receiver :4318 (本地)              │
          │  sha256(token) 校验 + cluster_id 强制重写 │
          │  → 中央 TimescaleDB(of-record)          │
          └─────────────────────────────────────────┘

3.2 Token 下发与轮换

  1. Token 存于 Infisical /otlp/{cluster_id}/PRIMARY_TOKEN(+ SECONDARY_TOKEN 用于零停机轮换)
  2. Manager Admin API 触发 rotate(写 PRIMARY/SECONDARY),ESO 同步到 K8s Secret tfrs-otlp-bearer
  3. Receiver 侧对 token 做 sha256 比对,并按 cluster 强制重写 cluster_id,防伪造
  4. 契约与轮换细节详见 TFRM-119docs/specs/otlp-receiver-contract.md

四、.env.prod 密钥分类

.env.prod 中的环境变量按安全级别分类:

高敏感(泄露可直接造成资金损失)

变量 说明
ALIPAY_APP_PRIVATE_KEY 支付宝应用私钥
WECHAT_MCH_PRIVATE_KEY 微信商户私钥
WECHAT_APIV3_KEY 微信 APIv3 密钥
SECRET_ENCRYPTION_KEY AES-256-GCM 数据加密密钥
JWT_SECRET JWT 签名密钥
ADMIN_JWT_SECRET Admin JWT 签名密钥
OIDC_SIGNING_KEY 管理域 OIDC ID token 的 RS256 私钥(base64 编码 PEM);泄露可伪造 OIDC 身份
OIDC_CLIENT_SECRET oauth2-proxy 的 OIDC client_secret(亦用于派生 auth code 加密密钥)
ACCESS_TOKEN_SIGNING_KEY[_SECONDARY] 连接数据面短 JWT 的 RS256 私钥(PRIMARY [+ 可选 SECONDARY 轮换槽],base64 PEM);泄露可伪造短 JWT。独立于上方 OIDC keyset。零中断轮换三步流见 08-access-token-signing-key-rotation.md

中敏感(泄露可导致数据访问)

变量 说明
DB_PASSWORD PostgreSQL 密码
REDIS_PASSWORD Redis 密码
INFISICAL_CLIENT_SECRET Infisical Machine Identity 密钥
COS_SECRET_KEY 腾讯云对象存储密钥
SMS_TENCENT_SECRET_KEY 腾讯云短信密钥

低敏感(配置信息)

变量 说明
GIN_MODE / LOG_LEVEL 运行模式
REGISTRY / REPO / IMAGE_TAG 镜像信息
DB_PORT / DB_NAME / DB_DRIVER 数据库连接参数
OIDC_ENABLED / OIDC_ISSUER_URL / OIDC_CLIENT_ID / OIDC_REDIRECT_URIS / OIDC_SIGNING_KEY_ID 管理域 OIDC 非机密配置

管理域 OIDC Provider 凭据生成(TFRM-143): - 签名私钥:openssl genrsa 2048 | base64 -w0 → 写入 Infisical OIDC_SIGNING_KEY(≥2048 位;admin-service 启动期解码校验,PKCS#1/#8 均可)。轮换:换 OIDC_SIGNING_KEY 并改 OIDC_SIGNING_KEY_ID 以更新 JWKS kid。 - OIDC_CLIENT_SECRETopenssl rand -hex 32(≥16 字符;同时用于派生 auth code 的 AES 加密密钥,须稳定)。与 Operator 侧 oauth2-proxy 的 client_secret(存为 K8s Secret)保持一致。 - OIDC_REDIRECT_URIS:逗号分隔,填各集群的 oauth2-proxy callback(auth host,非 jaeger host),如 https://auth.enaic.turingfocus.cn/oauth2/callback。 - OIDC_CLIENT_SECRET 须与被纳管集群内 K8s Secret tfr-mgmt-system/oauth2-proxy-client-secretclient-secret 同值(Operator 经 clientSecretRef 读取)。 - 全部仅当 OIDC_ENABLED=true 时校验生效;暴露面与 Nginx 直连见 02-network.md §2.2完整端到端落地清单(含 K8s Secret、TFRCluster CR、CLB auth 子域、Operator 最低版本 0.5.1-dev10)见 02-network.md §2.7

密钥流转链路

Infisical (唯一真实来源)
    ├─→ CNB CI/CD 密钥仓库 (tfrsmanager_env.prod.yml)
    │     └─→ scripts/env-keys.txt 白名单过滤
    │           └─→ .env.prod → 传输到 /opt/tfrs/
    └─→ /otlp/{cluster_id}/PRIMARY_TOKEN (集群初始化 / Admin rotate 写入)
          └─→ ESO 同步 → K8s Secret tfrs-otlp-bearer

五、安全检查清单

定期检查(建议每月):

  • [ ] SSL 证书是否即将过期(特别是手动上传的证书)
  • [ ] Infisical Machine Identity 是否有异常登录(Access Control → 查看 Last Logged In)
  • [ ] OTLP Receiver 未对外暴露(curl http://<prod_ip>:4318 应无响应,仅经 metrics 子域 Nginx 反代)
  • [ ] 所有业务端口仅绑定 127.0.0.1(ss -tlnp | grep -v 127.0.0.1 应仅有 80/443)
  • [ ] Infisical 备份正常执行(/opt/infisical-infra/backup/backup.log