feat: deliver Sense audits to Bell (T-016)
Harness governance / validate (push) Has been cancelled
Harness governance / validate (pull_request) Has been cancelled

This commit is contained in:
QiuSW
2026-08-11 00:24:32 +08:00
parent aca22f4667
commit 4be2386421
35 changed files with 2188 additions and 42 deletions
+19 -4
View File
@@ -1,6 +1,6 @@
# Sense 控制面、准入投影与本地审计契约 v1
> 冻结日期:2026-08-07。Control API 契约版本:`1.0.0`。Sense 是设备期望态的提供方;Bell 是 Tenant、Site、Area、RBAC、配额与全局审计的所有者。T-011 已实现 Control API handler 与 PostgreSQL 一致性边界;Bell 管理服务、JWT/OIDC 和 Outbox relay 仍未实现。
> 冻结日期:2026-08-11。Control API 与审计 relay 契约版本:`1.0.0`。Sense 是设备期望态的提供方;Bell 是 Tenant、Site、Area、RBAC、配额与全局审计的所有者。T-016 已实现 Sense Outbox 到 Bell 的内部 relay;Bell 公共管理服务与 JWT/OIDC 仍未实现。
## 契约文件
@@ -9,8 +9,9 @@
| [`sense-control-v1.openapi.json`](sense-control-v1.openapi.json) | Sense | Bell 管理面、受控集成方 | 设备查询、创建、修改、启停与批量操作 |
| [`site-quota-v1.sql`](site-quota-v1.sql) | Bell | Sense | 单 PostgreSQL 实例内的站点视频配额只读投影 |
| [`area-policy-v1.sql`](area-policy-v1.sql) | Bell | Sense | Area 归属与 `capture_policy` 只读投影 |
| [`sense-device-audit-v1.schema.json`](sense-device-audit-v1.schema.json) | Sense | 本地 Outbox;未来 Bell relay | 脱敏设备操作审计事实,不包含传输协议 |
| [`sense-device-audit-v2.schema.json`](sense-device-audit-v2.schema.json) | Sense | 本地 Outbox;未来 Bell relay | v1 后继,增加脱敏配置修改受理事实;v1 文件保持不变 |
| [`sense-device-audit-v1.schema.json`](sense-device-audit-v1.schema.json) | Sense | 本地 Outbox;Bell relay | 脱敏设备操作审计事实,不包含传输协议 |
| [`sense-device-audit-v2.schema.json`](sense-device-audit-v2.schema.json) | Sense | 本地 Outbox;Bell relay | v1 后继,增加脱敏配置修改受理事实;v1 文件保持不变 |
| [`sense-audit-relay-v1.openapi.json`](sense-audit-relay-v1.openapi.json) | Bell | Sense | 内部批量端点、HMAC、逐项确认、nonce 防重与重试边界 |
OpenAPI 的 `/api/v1` 路径是公共控制面边界;`/healthz`、`/readyz` 仍是非业务运维探针。v1 不提供设备删除:停用设备使用期望态接口,保留设备、操作和审计历史。Site、Area、配额、RBAC 和审计聚合不由 Sense 提供 CRUD。
@@ -57,7 +58,19 @@ T-010 冻结 `bell.area_policy_v1` 的列顺序为 `tenant_id/site_id/area_id/ca
`sense-device-audit-v1.schema.json` 继续冻结创建与期望态两类事实且不原地扩展严格枚举。T-011 新增 v2 后继,兼容 v1 两类事件并增加 `device.configuration.accepted`;该 payload 只保存是否变化、字段名和 Area 逻辑 ID,不保存字段值。主体类型为 `user | service | system`,投影版本与 generation 随事实保存;endpoint、credential、profile token、path、密码、完整流 URI 或 MediaMTX 配置始终禁止进入审计。
PostgreSQL repository 必须在设备创建/期望态事务内写 `sense.device_operation_outbox`;Outbox 失败回滚业务写入。相同期望态不增加 generation,但仍产生独立审计事实。Schema 不是 Bell relay 协议:传输端点、签名、批量确认、重放窗口和留存由后续任务冻结。
PostgreSQL repository 必须在设备创建/期望态事务内写 `sense.device_operation_outbox`;Outbox 失败回滚业务写入。相同期望态不增加 generation,但仍产生独立审计事实。事件 schema 继续只定义事实;传输由 `sense-audit-relay-v1.openapi.json` 独立冻结。
## Sense → Bell 审计 relay
Sense 向 `/internal/v1/audit-events:batch` 每批发送 1~100 个事件,请求体不超过 1 MiB、deadline 10 秒。请求用外部文件中的至少 32 字节 secret 做 HMAC-SHA256,canonical string 为 method、path、Unix 秒、随机 nonce 与 body SHA-256 的换行拼接;非回环地址必须使用 HTTPS。Bell 允许 300 秒时钟偏差并将 `(key_id, nonce)` 收据保留 600 秒:相同请求摘要返回原结果,不同摘要返回 `409 replay_conflict`。
Outbox 用 30 秒数据库时钟 lease、单调 fencing token 和 `FOR UPDATE SKIP LOCKED` 协调实例。`accepted/duplicate` 才标记 delivered;逐项 `rejected` 进入 dead letter;网络、5xx、认证失败或缺失结果以 1 秒起步、最多 300 秒指数退避。Sense 不直接访问 Bell schema,Bell 不读取 Sense Outbox;全局 `bell.audit_events` 不自动删除,只有短期 relay receipt 自动过期。
两端读取同格式的仓库外 key 文件;Bell 可同时接受多个 key,Sense 用 `SENSE_AUDIT_RELAY_KEY_ID` 选择一个,便于先加新 key、切换发送端、再移除旧 key。占位结构如下,`secret_base64url` 必须替换为至少 32 个随机字节的无填充 base64url,不能提交真实值:
```json
{"version":1,"keys":[{"key_id":"sense-a","secret_base64url":"<external-secret>"}]}
```
## 兼容与废弃
@@ -73,8 +86,10 @@ PostgreSQL repository 必须在设备创建/期望态事务内写 `sense.device_
```powershell
python -m json.tool docs/contracts/sense-control-v1.openapi.json | Out-Null
python -m json.tool docs/contracts/sense-device-audit-v2.schema.json | Out-Null
python -m json.tool docs/contracts/sense-audit-relay-v1.openapi.json | Out-Null
python -m unittest discover -s tests -p "test_sense_control_contract.py"
python -m unittest discover -s tests -p "test_sense_control_implementation.py"
python -m unittest discover -s tests -p "test_sense_audit_relay_contract.py"
```
测试同时校验 OpenAPI 结构、生成 server glue、HTTP handler 与 PostgreSQL migration/事务;它不替代 Bell 消费方联合验收或客户现场容量验证。