Files
lingxi/docs/工程规范/09-环境变量与密钥规范.md
T
Stev_Wang 00ae12435e docs(specs): add AGENTS.md and engineering guidelines
项目尚无统一工程规范,AI 助手与研发各自发挥导致返工风险。建立
总纲 + 细则两层结构:AGENTS.md 只写硬约束与索引(14 条红线、技术栈
基线、仓库结构、命令契约),细则拆为 10 份文档覆盖 Git、代码风格、
格式化、API 与路由、数据库、测试与 CI、Review、日志、密钥、资产命名。

影响面:仅文档。约束力从本轮起对新建代码生效;与现状冲突处以文档为准。
回滚方式:git revert 本提交。
2026-11-02 15:09:51 +08:00

132 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 09 · 环境变量与密钥规范
| 项 | 内容 |
| --- | --- |
| 文档版本 | V1.0(2026-11-02) |
| 依据 | 技术架构 附录 C(关键环境变量)、§2.8(安全)、§4.1 / §4.4 |
| 适用范围 | 所有环境(dev / staging / prod)、CI、本地开发 |
| 强制级别 | 强制 |
---
## 1 基本规则
- `ENV-01` 只有 `.env.example` 入库;`.env`、`.env.local`、`.env.*.local` 一律不入库(`.gitignore` 已覆盖)。
- `ENV-02` 变量名 `UPPER_SNAKE_CASE`,按前缀分组;新增变量必须同时更新 `.env.example`、本文附录、部署配置三处。
- `ENV-03` 应用启动时用 Zod 校验环境变量,**缺失或非法直接 fail fast**,禁止带默认值「悄悄跑起来」。
- `ENV-04` 代码中只能通过集中配置模块读取(`config/env.ts`),**禁止**到处 `process.env.XXX`。
- `ENV-05` 禁止在仓库、PR、聊天工具、日志中传递真实密钥;示例值用 `xxx` / `changeme`。
- `ENV-06` 三个环境密钥**完全独立**:dev / staging / prod 不得复用同一套数据库、Redis、S3、JWT、AI 密钥。
---
## 2 变量清单(前缀分组)
### 运行与数据库
| 变量 | 说明 | 示例 |
| --- | --- | --- |
| `NODE_ENV` | 运行环境 | `development` / `production` |
| `DATABASE_URL` | PG 连接串 | `postgresql://user:pass@host:5432/lingxi` |
| `REDIS_URL` | Redis 连接串 | `redis://host:6379/0` |
| `QUEUE` | worker 订阅队列名 | `image:render` |
### 对象存储(S3 协议)
| 变量 | 说明 |
| --- | --- |
| `S3_ENDPOINT` | MinIO / 云 OSS 端点 |
| `S3_ACCESS_KEY` / `S3_SECRET_KEY` | 访问密钥(按环境独立) |
| `S3_BUCKET_ASSETS` / `S3_BUCKET_RENDERS` / `S3_BUCKET_TEMP` | 资产 / 产物 / 临时桶 |
| `S3_BUCKET_ARCHIVE` / `S3_BUCKET_UPLOADS` / `S3_BUCKET_EXPORTS` | 归档 / 上传 / 导出桶 |
### 认证与安全
| 变量 | 说明 |
| --- | --- |
| `JWT_SECRET` / `JWT_REFRESH_SECRET` | 长度 ≥ 32,按环境独立 |
| `ENCRYPTION_KEY` | AES-256-GCM 主密钥(加密 AI 供应商密钥等) |
| `PUBLIC_LINK_HMAC_SECRET` | 免登录审核 / 分享链接签名密钥 |
### AI 接入
| 变量 | 说明 |
| --- | --- |
| `AI_PROVIDER_<NAME>_API_KEY` | 按供应商分(如 `AI_PROVIDER_JIMENG_API_KEY`) |
| `AI_PROVIDER_<NAME>_BASE_URL` | 自定义端点(可选) |
| `AI_ROUTE_REFRESH_MS` | 路由表缓存刷新间隔 |
> 供应商 API Key 以加密形式存库(`ai_configs`)时,环境变量只用于**首次注入 / 灾备**;运行时读取库内配置,避免多处真相。
### 媒体处理
| 变量 | 说明 |
| --- | --- |
| `FFMPEG_PATH` / `FFPROBE_PATH` | 二进制路径(镜像内固定) |
| `MAX_UPLOAD_MB` | 单文件上限 |
| `WORKER_CONCURRENCY` | 单 worker 并发 |
### 成本与开关
| 变量 | 说明 |
| --- | --- |
| `COST_SOFT_LIMIT` / `COST_HARD_LIMIT` | 预算软 / 硬限(默认 0.8 / 1.0) |
| `FEATURE_VIDEO` | 视频线开关 |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | 链路追踪导出端点 |
---
## 3 密钥管理
| 项 | 规则 |
| --- | --- |
| 存储 | 生产用云 KMS / Vault / Secrets Manager;**禁止**明文写进 compose 或镜像 |
| 注入 | CI/CD 注入环境变量;本地用 `.env.local`(不入库) |
| 加密 | AI 供应商密钥等入库字段用 AES-256-GCM,密钥不落同一库 |
| 权限 | 应用 DB 账号非 superuser;MinIO 按桶最小权限;CI 只读必要范围 |
| 轮换 | JWT / HMAC / 加密密钥至少每 6 个月或人员变动时轮换;轮换需兼容期(新旧并存) |
| 审计 | 密钥变更记审计(谁、何时、哪个 key 的版本号,**不记值**) |
- `ENV-07` 前端只能暴露 `VITE_PUBLIC_*` 前缀变量;构建产物必须扫描确认无服务端密钥。
- `ENV-08` 禁止把密钥拼进 URL / query / 日志 / 异常信息。
- `ENV-09` 本地开发连的 MinIO / PG 凭据只能是 dev 值,且与生产不一致。
---
## 4 泄露处置(30 分钟内)
1. **立即轮换**对应密钥(先轮换再排查,不等待确认)。
2. 撤销相关 token / session,作废签名链接。
3. 检查访问日志与 `ai_usage`,评估是否被滥用(尤其 AI 费用)。
4. 用 `git filter-repo` 清理历史并强制全员重新 clone(见 [01](01-Git规范.md) `GIT-20`)。
5. 24 小时内出复盘:泄露路径、影响面、改进项(通常补 CI 扫描 / pre-commit)。
- `ENV-10` 泄露事件必须记录在案,**禁止**「悄悄换掉当没发生」。
---
## 5 本地开发
```bash
cp .env.example .env.local # 填 dev 值(不得填生产值)
pnpm compose:up # PG 18 / Redis 7.4 / MinIO
pnpm db:migrate && pnpm db:seed
pnpm dev
```
- `ENV-11` 禁止 `docker compose down -v` 清库;重置数据用 `pnpm db:reset`。
- `ENV-12` 本地不得连生产数据库 / 生产对象存储 / 生产 AI 供应商(费用与数据风险)。
- `ENV-13` 开发机 Node 版本由 `.nvmrc` 固定,`package.json` 声明 `engines`,`preinstall` 用 `only-allow pnpm` 拦截其他包管理器。
---
## 6 检查清单
- [ ] 新增变量已写 `.env.example` 与本文
- [ ] 启动校验覆盖新变量,缺失即失败
- [ ] 未在代码中散读 `process.env`
- [ ] 三环境密钥独立,未复用
- [ ] 无密钥进日志 / URL / 前端 bundle
- [ ] 生产密钥来自 KMS / Secrets Manager
- [ ] 轮换与泄露处置流程已知晓