Files
heicode-win/docs/deployment/azure-production-deploy-guardrails.md
T
gongzhiyong ba02ae5be7 feat: align manager agnet boundaries
- add Manager user_context, NewAPI billing_context, and Agnet agent_runtime deployment fields

- move resource binding/grant scope toward user-owned binding_scope and secret_ref-only paths

- document OpenBao internal access and unified heicode.xinghanlab.com routing boundaries

- fix Manager session user id preservation after external auth login
2026-05-04 09:28:03 +08:00

189 lines
9.0 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.
# Azure 生产部署安全守卫与验证计划
本文用于 Heicode Manager / Agnet / NewAPI 相关生产发布前的人工执行检查。它只描述安全命令、环境变量名和验证项,不保存任何真实地址、账号、密码、Token、连接串、SSH key 或云访问密钥。
适用范围:Azure VM、Azure PostgreSQL、Azure Redis、Git 同步、Nginx 统一入口、Heicode Manager 容器、OpenBao 内网密钥保管、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 放入请求体。 |
| OpenBao | 只允许 Manager/Agnet 受控网络访问;如果 Manager 提供客户端验证和绑定接口,OpenBao 不暴露公网路由。 |
| 生产动作 | 执行 `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='<azure-vm-host-or-ip>'
export VM_USER='<ssh-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=<azure-postgresql-connection-string>
REDIS_CONN_STRING=<azure-redis-connection-string>
SESSION_SECRET=<generated-session-secret>
HEICODE_ROOT_EMAILS=<comma-separated-root-emails-if-needed>
HEICODE_ADMIN_EMAILS=<comma-separated-admin-emails-if-needed>
```
验证只打印 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 托管实例。
公网入口约定:
- 对外域名统一使用 `heicode.xinghanlab.com`。
- Nginx 负责按路由转发 Manager 与 NewAPI,例如 Manager 主站、NewAPI 受控 API 或健康检查路由。
- OpenBao 仅供 Manager/Agnet 服务端访问,不通过 `heicode.xinghanlab.com` 暴露给浏览器用户。
- 若需要 OpenBao 运维 UI,也必须走临时 SSH tunnel、VPN、内网跳板或单独受保护管理入口,不走普通 SaaS 用户路由。
构建和启动:
```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='<agnet-platform-base-url>'
export MANAGER_SERVICE_TOKEN_SECRET_REF='<secret-ref-only>'
export USER_ID='<manager-user-id>'
export BINDING_SCOPE='<resource-binding-scope>'
# 真实 token 由运行环境注入;禁止把 token 字面值写入命令历史或文档。
curl -fsS -X POST "$AGNET_BASE_URL/api/agnet/deployments" \
-H 'Content-Type: application/json' \
-H "X-User-Id: $USER_ID" \
-H "X-Binding-Scope: $BINDING_SCOPE" \
-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`。 |
| Nginx 公网入口 | `curl -fsS https://heicode.xinghanlab.com/api/status` | 返回 Manager 健康状态;DNS 需解析到生产入口。 |
| OpenBao 暴露面 | `curl -fsSI https://heicode.xinghanlab.com/v1/sys/health` | 普通公网入口不应返回 OpenBao 健康信息;预期为无路由、403 或 404。 |
| 容器状态 | `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 实际部署。