diff --git a/docs/README.md b/docs/README.md index 2d3b99b..b68c930 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # Heicode Docs -当前 `docs/` 只保留四类主线文档: +当前 `docs/` 只保留五类主线文档: | 文档 | 用途 | |------|------| @@ -8,7 +8,8 @@ | [`plan.md`](./plan.md) | 按当前共识拆出的实施计划 | | [`integration/Heicode-登录接口对接文档.md`](./integration/Heicode-登录接口对接文档.md) | 已上线登录接口对接文档 | | [`integration/agnet-platform-request-contract.md`](./integration/agnet-platform-request-contract.md) | Manager 请求 Agnet 平台时携带的部署、日志、监控、事件与审计接口参数 | +| [`deployment/azure-production-deploy-guardrails.md`](./deployment/azure-production-deploy-guardrails.md) | Azure VM / PostgreSQL / Redis / Agnet / NewAPI 生产部署前的安全守卫、环境变量注入和验证计划 | -旧 Agnet API 草案、旧里程碑、旧架构说明和旧上手材料不再作为实施依据。后续文档和实现以 `heicode.md` 与 `plan.md` 为准。 +旧 Agnet API 草案、旧里程碑、旧架构说明和旧上手材料不再作为实施依据。后续文档和实现以 `heicode.md` 与 `plan.md` 为准;生产部署操作以安全守卫文档约束,且不得覆盖产品/架构主线。 代码中的过渡期命名、旧接口注释或旧 UI 文案只作为现状参考;若与 `heicode.md` / `plan.md` 冲突,应先更新实现或另行补充当前主线文档,不得恢复旧 Agnet/M1-M5 草案作为依据。 diff --git a/docs/deployment/azure-production-deploy-guardrails.md b/docs/deployment/azure-production-deploy-guardrails.md new file mode 100644 index 0000000..6fe2726 --- /dev/null +++ b/docs/deployment/azure-production-deploy-guardrails.md @@ -0,0 +1,177 @@ +# Azure 生产部署安全守卫与验证计划 + +本文用于 Heicode Manager / Agnet / NewAPI 相关生产发布前的人工执行检查。它只描述安全命令、环境变量名和验证项,不保存任何真实地址、账号、密码、Token、连接串、SSH key 或云访问密钥。 + +适用范围:Azure VM、Azure PostgreSQL、Azure Redis、Git 同步、Heicode Manager 容器、Agnet 平台联调、NewAPI 网关能力验证。 + +## 1. 执行原则 + +| 项 | 要求 | +|---|---| +| 凭据处理 | 只使用 VM 环境、交互式 SSH、未提交的 `.env`、Key Vault 或 `secret_ref`;禁止把真实密钥写入 Git、Markdown、终端报告或 team state。 | +| Git 发布 | 仅允许快进同步已审核提交;禁止在生产 VM 上提交代码或保存临时补丁。 | +| 数据库/Redis | Azure PostgreSQL / Redis 连接串只写入 VM 本地 `.env` 或 Secret Store;验证时只打印变量名和连通性结果,不打印值。 | +| Agnet / NewAPI | Manager 只传 `secret_ref`、部署计划、资源授权和审计上下文;禁止把明文云账号、数据库密码、模型 Key 放入请求体。 | +| 生产动作 | 执行 `up -d`、迁移、重启、回滚前必须记录当前镜像/提交和健康检查 URL;失败时停止扩大变更。 | + +## 2. 本地发布前检查 + +在本地工作区执行,确认没有未提交变更和明文凭据: + +```bash +git status --short +git diff --check + +# 只允许命中占位符、变量名或文档中的禁用词说明;若命中真实值,立即停止。 +grep -RIn --exclude-dir=.git --exclude-dir=node_modules --exclude='*.jpg' \ + -E '(password|passwd|token|secret|private_key|access_key|credential|SQL_DSN|REDIS_CONN_STRING)' \ + docs heicode/bin heicode/docker-compose.azure-vm.yml +``` + +预期: + +- `git status --short` 只显示准备发布的已审核文档/代码变更。 +- `git diff --check` 无输出。 +- `grep` 结果不包含真实凭据;只允许出现 `secret_ref`、环境变量名、占位符或安全规则说明。 + +## 3. Git 同步守卫 + +在生产 VM 上只执行快进同步,避免产生生产端漂移: + +```bash +export VM_HOST='' +export VM_USER='' +export REMOTE_DIR='/opt/heicode' +export REMOTE="${VM_USER}@${VM_HOST}" + +ssh "$REMOTE" "cd '$REMOTE_DIR' && git status --short" +ssh "$REMOTE" "cd '$REMOTE_DIR' && git fetch --all --prune" +ssh "$REMOTE" "cd '$REMOTE_DIR' && git merge --ff-only origin/main" +ssh "$REMOTE" "cd '$REMOTE_DIR' && git rev-parse --short HEAD" +``` + +若 `git status --short` 非空,先停止部署并人工判断;不要在 VM 上直接 `git reset --hard`,除非已有明确回滚授权。 + +## 4. VM 本地 `.env` 注入 + +真实连接串只能进入 VM 本地未提交 `.env` 或 Secret Store。推荐用交互式编辑器写入,不在命令行参数中携带值: + +```bash +ssh -t "$REMOTE" "cd '$REMOTE_DIR/heicode' && umask 077 && \${EDITOR:-vi} .env" +``` + +`.env` 至少应包含以下键,值由运维在交互式 SSH 会话中填入: + +```text +SQL_DSN= +REDIS_CONN_STRING= +SESSION_SECRET= +HEICODE_ROOT_EMAILS= +HEICODE_ADMIN_EMAILS= +``` + +验证只打印 key,不打印 value: + +```bash +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && test -f .env && chmod 600 .env && awk -F= '/^[A-Z0-9_]+=/{print \$1}' .env | sort" +``` + +## 5. Azure PostgreSQL / Redis 连通性验证 + +优先通过应用容器的健康检查间接验证。若必须直接验证,只输出成功/失败: + +```bash +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && docker compose -f docker-compose.azure-vm.yml --env-file .env config --services" +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && docker compose -f docker-compose.azure-vm.yml --env-file .env run --rm heicode sh -lc 'test -n \"\$SQL_DSN\" && test -n \"\$REDIS_CONN_STRING\" && echo env-present'" +``` + +禁止执行会打印完整环境的命令,例如 `env`、`printenv`、`docker inspect` 全量输出或 `docker compose config` 全量输出。 + +## 6. Heicode Manager / NewAPI 容器部署 + +当前仓库的 Heicode 服务保留 NewAPI 网关能力;生产部署以 `heicode/docker-compose.azure-vm.yml` 为入口,PostgreSQL / Redis 使用 Azure 托管实例。 + +构建和启动: + +```bash +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && docker compose -f docker-compose.azure-vm.yml --env-file .env build heicode" +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && docker compose -f docker-compose.azure-vm.yml --env-file .env up -d heicode" +``` + +健康检查: + +```bash +ssh "$REMOTE" "curl -fsS http://127.0.0.1:3000/api/status | grep -q '\"success\":true' && echo heicode-health-ok" +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && docker compose -f docker-compose.azure-vm.yml --env-file .env ps heicode" +``` + +如使用现有脚本,仍需通过环境变量传参,不在命令里写真实凭据: + +```bash +VM_HOST="$VM_HOST" VM_USER="$VM_USER" REMOTE_DIR="$REMOTE_DIR/heicode" \ + IMAGE_TAG='heicode-manager:local' HEALTH_URL='http://127.0.0.1:3000/api/status' \ + ./heicode/bin/azure_vm_deploy.sh +``` + +## 7. Agnet 平台联调守卫 + +Manager 请求 Agnet 平台时遵循 `docs/integration/agnet-platform-request-contract.md`: + +- `resource_grants[].secret_ref` 必须是 Secret Store 引用,不能是明文密钥。 +- `repo_url` 不能包含用户名、密码或 Token。 +- `metadata`、`constraints`、`audit` 的 key 和 value 都需要脱敏检查。 +- 高风险部署设置 `risk_level=high`,并保留审批或人工确认记录。 + +安全 smoke request 模板: + +```bash +export AGNET_BASE_URL='' +export MANAGER_SERVICE_TOKEN_SECRET_REF='' +export TENANT_ID='' +export PROJECT_ID='' + +# 真实 token 由运行环境注入;禁止把 token 字面值写入命令历史或文档。 +curl -fsS -X POST "$AGNET_BASE_URL/api/agnet/deployments" \ + -H 'Content-Type: application/json' \ + -H "X-Tenant-Id: $TENANT_ID" \ + -H "Idempotency-Key: deploy-$(date +%Y%m%d%H%M%S)" \ + -H "Authorization: Bearer $MANAGER_SERVICE_TOKEN" \ + --data @docs/integration/safe-agnet-deploy-example.json +``` + +若没有 `safe-agnet-deploy-example.json`,先用本地临时文件生成并确认只包含 `secret_ref`,不要提交包含环境特定值的 payload。 + +## 8. 发布后验证清单 + +| 验证项 | 安全命令 | 通过标准 | +|---|---|---| +| 服务健康 | `curl -fsS http://127.0.0.1:3000/api/status` | 返回 `success=true`。 | +| 容器状态 | `docker compose ... ps heicode` | `heicode` 为 running/healthy。 | +| Git 版本 | `git rev-parse --short HEAD` | 与已审核提交一致。 | +| DB/Redis 注入 | `awk -F= ... .env` | 只打印 key,包含 `SQL_DSN`、`REDIS_CONN_STRING`。 | +| 登录链路 | 调用登录文档中的生产验证流程 | 不在日志或报告输出 token。 | +| Agnet 部署 | 查询部署状态/事件/审计接口 | 能看到 deployment、events、audit,且无明文凭据。 | +| NewAPI 网关能力 | 使用 Manager 受控模型调用或健康接口 | 只记录 request id、状态码、模型名,不记录 provider key。 | + +## 9. 回滚与停止条件 + +立即停止部署并进入回滚/人工排障的条件: + +1. 任一日志、响应、Markdown 或 Git diff 中出现真实密钥。 +2. `git merge --ff-only` 失败或 VM 工作区有未知改动。 +3. 健康检查连续失败。 +4. Agnet 平台返回的事件/审计中包含明文凭据。 +5. 数据库迁移或容器启动错误无法在一次重试内恢复。 + +回滚指针: + +```bash +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && cat .last_success_image 2>/dev/null || true" +ssh "$REMOTE" "cd '$REMOTE_DIR/heicode' && IMAGE_TAG=\$(cat .last_success_image) docker compose -f docker-compose.azure-vm.yml --env-file .env up -d heicode" +``` + +若 `.last_success_image` 为空,回滚到上一个已验证 Git commit,并重新执行健康检查。 + +## 10. 本次文档产物状态 + +本文件仅准备部署守卫和验证计划;未执行 Git push、SSH 登录、Azure 资源变更、生产容器重启或 Agnet 实际部署。