refactor(access): 统一分层白名单权限语义

取消跨主体专属占用,按租户、用户组、用户、当前 API Key 和 scope 分层求交,并在任务落库前统一校验候选。\n\n增加旧 allow 规则归档清理迁移、脱敏审计工具和回滚运行手册,补齐主体隔离、deny 优先及列表与运行时一致性测试。
This commit is contained in:
2026-08-03 15:43:49 +08:00
parent c9393af43a
commit 7376d6fab6
20 changed files with 1490 additions and 513 deletions
@@ -0,0 +1,64 @@
# 访问规则白名单语义迁移
迁移 `0102_access_rule_allow_whitelist_semantics` 将旧版跨主体“专属占用”
规则切换为分层白名单。迁移会归档并删除已有的全部 `allow`,保留 `deny`
不变;发布后新建的 `allow` 将按白名单解释。
## 发布前
1. 暂停管理端和用户工作台的权限配置写入,并停止会创建访问规则的
acceptance、smoke 或运维脚本。仅依赖数据库表锁不足以覆盖迁移前快照到
应用切换之间的时间窗口。
2. 使用只读数据库账号导出脱敏基线:
```bash
AI_GATEWAY_ACCESS_RULE_AUDIT_DATABASE_URL='<只读数据库连接>' \
scripts/acceptance/export-access-rule-audit.sh export \
--output dist/access-rule-audit/before.json
```
3. 保存命令输出中的总规则数、`allow`/`deny` 数量和 SHA-256。快照仅包含按
主体类型、效果、资源类型、状态聚合的计数和摘要,不包含主体 ID、资源 ID、
API Key Secret 或规则元数据。
4. 确认权限写入仍处于暂停状态,再开始应用发布和数据库迁移。
## 迁移后校验
继续使用只读数据库账号执行:
```bash
AI_GATEWAY_ACCESS_RULE_AUDIT_DATABASE_URL='<只读数据库连接>' \
scripts/acceptance/export-access-rule-audit.sh verify \
--before dist/access-rule-audit/before.json \
--output dist/access-rule-audit/after.json
```
只有命令返回 `access_rule_audit_verify=PASS` 才能恢复权限配置写入。该校验同时
证明:
- 迁移前 `allow` 数量和摘要与归档表一致;
- 当前表中的旧 `allow` 数量为零;
- `deny` 数量和内容摘要与迁移前一致。
随后按生产验收清单创建隔离用户组和 API Key,验证父级继承、分层白名单交集、
同层并集、`deny` 优先及兄弟主体隔离。验收结束后删除隔离身份、Key 和规则,
并确认没有遗留任务、队列项或并发租约。
## 回滚限制
应用回滚不会恢复旧版“专属占用”规则。新版本一旦写入白名单 `allow`,禁止直接
切回旧应用,否则旧代码会把新白名单解释成跨主体排他规则。
必须回滚到旧应用时:
1. 再次暂停所有访问规则写入和 acceptance/smoke
2. 导出当前脱敏快照,并单独备份数据库;
3. 明确识别并清理迁移完成后创建的 `allow`,不得删除 `deny`,也不得直接恢复
归档中的旧 `allow`
4. 校验当前 `allow=0` 且 `deny` 摘要未变化后,才允许切换旧应用;
5. 恢复旧规则必须作为独立、受审的数据恢复操作处理,不能包含在应用自动回滚
中。
迁移本身会在事务中锁定 `gateway_access_rules` 的写入,校验归档数量和摘要后才
删除旧 `allow`。若检测到归档不一致,事务会失败;若迁移完成后出现新白名单,
直接重复执行迁移也会失败,不会误删新规则。