feat(preflight): confirm + audit + tamper-proof version check (#41)
完成 preflight EPIC(#29)的最后一子项 #41: - POST /api/heicode/preflight/confirm:重算摘要 → 仅 ready 时可确认 → 派生防篡改 版本哈希 → 写审计事件 preflight.confirmed(谁/何时/哪个 version)→ 返回 version。 - 防篡改版本 computePreflightVersion:在**稳定安全面**(template + 资源 binding_id/type/provider/name/status/has_secret + 高危 enum + 必需缺失项)上做 sha256,刻意排除易变预算数字/agent_slot,避免版本无意义抖动。 - 部署校验:POST /api/heicode/agents 新增可选 preflight_version。默认仅在带了它时 校验(向后兼容);HEICODE_PREFLIGHT_REQUIRED=true 时强制。确认后资源/模板/高危面 漂移或被篡改 → 版本不匹配 → 部署拒绝。 - 重构:抽出 buildPreflightSummary(GET/confirm/deploy 共用);GET 现也回 version。 测试:版本确定性/稳定性(不随预算变)、资源篡改翻转版本、normalizeBindingIDs。 go build/vet 干净,controller preflight 测试全过。文档 §4.1/§4.1.1 更新。 Affects: Manager only(新增 confirm 端点 + 部署可选校验,默认向后兼容)。 无计费/审计 schema 改动(复用既有 agent_audit_events)。 Closes #41 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -152,7 +152,8 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) )
|
||||
|
||||
| 方法 | 路径 | 鉴权 | 说明 |
|
||||
|---|---|---|---|
|
||||
| GET | `/api/heicode/preflight?template_id=&binding_ids=1,2,3` | `UserOrV2DeviceAuth` | 返回缺失项 + 可读执行摘要 |
|
||||
| GET | `/api/heicode/preflight?template_id=&binding_ids=1,2,3` | `UserOrV2DeviceAuth` | 返回缺失项 + 可读执行摘要 + `version` |
|
||||
| POST | `/api/heicode/preflight/confirm` | `UserOrV2DeviceAuth` | 确认摘要 → 记审计 + 返回防篡改 `version`(#41) |
|
||||
|
||||
- `binding_ids` 同部署入参(逗号分隔或重复 key,可空)。
|
||||
|
||||
@@ -174,7 +175,8 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) )
|
||||
],
|
||||
"budget": { "remaining_quota":1234567, "quota_per_unit":500000, "tier_max_agents":5, "current_agents":1 },
|
||||
"approval_policy": { "mode":"per_high_risk_op" },
|
||||
"ready": false
|
||||
"ready": false,
|
||||
"version": "pfv1_3a9c…"
|
||||
}}
|
||||
```
|
||||
|
||||
@@ -182,8 +184,25 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) )
|
||||
- **`high_risk_ops`**:固定 enum —— `production_deploy` / `db_write` / `cloud_resource_delete` / `production_secret` / `large_budget`;由已绑资源类型推导,均 `requires_approval`。
|
||||
- **红线**:`resources` 只暴露 `type/provider/name/status/has_secret`(布尔),**绝不返回 `secret_ref`/`channelId`/`base_url`/价格**。
|
||||
- **`invalid_bindings`**:请求里无效 / 非本人 / 非 active 的绑定 id(不阻断,供前端提示)。
|
||||
- **`version`**:防篡改摘要版本(#41),由**稳定安全面**派生(template + 资源 + 高危 + 必需缺失项);**不含**易变的预算数字,故余额波动不会改版本。
|
||||
|
||||
> confirm + 审计 + 防篡改版本校验(#41)将作为 `POST /api/heicode/preflight/confirm` 后续补充;当前 preflight 为只读。
|
||||
### 4.1.1 确认 + 防篡改版本(#41)
|
||||
|
||||
`POST /api/heicode/preflight/confirm` body:`{ "template_id":"architect", "binding_ids":[17] }`
|
||||
|
||||
```json
|
||||
{ "success": true, "data": {
|
||||
"version": "pfv1_3a9c…", // 把它带到部署请求
|
||||
"template_id": "architect",
|
||||
"summary": { …同上执行摘要… },
|
||||
"confirmed": true
|
||||
}}
|
||||
```
|
||||
|
||||
- 仅当 `ready=true` 才能确认;否则返回 `POLICY_REJECTED`(先补齐缺失项)。
|
||||
- 确认会写一条审计事件 `preflight.confirmed`(谁 / 何时 / 哪个 `version`)。
|
||||
- **部署校验**:`POST /api/heicode/agents` 可带 `preflight_version`。HM 用**当前**资源/模板状态重算版本并比对——确认后资源被增删/改类型/改凭证、或模板变更 → 版本不匹配 → 部署被拒(`preflight changed…,re-run confirm`)。
|
||||
- 默认**仅在带了 `preflight_version` 时校验**(向后兼容,不带照常部署);设 `HEICODE_PREFLIGHT_REQUIRED=true` 则**强制**要求先 confirm。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user