# P3-WP10 多租户底座验证证据 ## 结论边界 独立最终复验已通过,本地工程状态为 `ENGINEERING_BASELINE_COMPLETE_MULTI_TENANCY_ACTIVATION_BLOCKED`。此前 `501`–`503` payload/GUC gateway 缺陷已由后续闭合控制链替代;此状态不激活 SaaS 或共享控制面,不配置真实 tenant/provider/secret,不代表企业 UAT 或生产完成。 2026-08-17 第四轮整改证据:`521` 撤销 PUBLIC/control/runtime/approver 对旧 lifecycle gateway 的执行,recover/delete 只能经 approval wrapper;`522` 使 quota worker 在同一受控事务中消费 digest-bound claim、reserve 后 settle 或 release;`523`–`524` 只为 queued retry 重臂已释放的 claim/attempt;`525` 使任何 live tenant/control data 在首个 downgrade step 即拒绝。真实 Docker PostgreSQL 已验证低权旧 gateway 拒绝、approved wrapper/API 正向、quota settled/released、三次 fail、restart/fence、并发和 downgrade fence。最终本地定向 suite 为 `33 unit/API + 13 real PostgreSQL = 46 passed`;Ruff、OpenAPI 483-operation byte parity、source/deployment/migration byte parity 与 `git diff --check` 通过。状态为 `ENGINEERING_BASELINE_COMPLETE_MULTI_TENANCY_ACTIVATION_BLOCKED`;外部 activation 仍为 `TBD_EXTERNAL`。 ## TDD 记录 - **当前整改 RED/GREEN:** `20260817_503` 下真实 `dataops_app` runtime 可自行设定 beta tenant GUC 并直接调用 `tenant_foundation_write`,即使调用者只应属于 alpha,攻击测试为 `1 failed`。`20260817_504` 未修改已应用迁移,只撤销共享 runtime 对 payload-authorized tenant gateways 和 `tenants` 根表的访问;同一攻击为 `1 passed`。这是紧急封堵,完整 authenticated claim/API replacement 尚未完成。 - RED:`test_wp10_tenant_context.py` 和 `test_wp10_tenant_boundaries.py` 在 `tenant_context` / `tenant_resources` 缺失时收集失败;最小闭合实现后 GREEN。 - RED:lifecycle/repository PostgreSQL 测试在模块/方法缺失时失败;`501` tenant foundation 与 `502` lifecycle gateway 后 GREEN。 - RED:迁移后重跑 role-init 时,真实 `dataops_app` runtime 能在设定 tenant GUC 后直 DELETE audit;role-init 的广泛 DML grant matrix 未排除 WP10 表。修复为先撤销且排除所有 `tenants`/`tenant_*` 表后,真实攻击 GREEN。 - RED:low-privilege migrator 从 `480` 到 head 时因缺少 `dataops_tenant_foundation_owner` member 被 `501` 前置检查拒绝;测试 role-init fixture 增加最小 owner membership/schema grant 后 GREEN,migrator 保持 `NOSUPERUSER,NOCREATEROLE`。 - RED:初版持久 outbox 在 `FORCE RLS` 下无法在尚未知道 tenant scope 时读取 worker UID;`514` 新增只允许 owner gateway 读取的 `outbox_uid -> tenant_id` lookup,先用持久映射设置 DB-local scope 再 lease outbox,未放宽 RLS;真实 Flask/PG worker GREEN。 - RED:从较新 head 降级时会先遇到后续迁移 guard,不能将安全拒绝稳定归因到最外层边界;`515` 作为 marker-only final head fence,在 tenant/control/outbox 任一数据存在时立即拒绝,live-data `515 -> 503` 攻击 GREEN,version 保持 `515`。 ## 本地 PostgreSQL 证据(Docker) - 初始只读 head:`20260813_500`;当前本地 Docker PostgreSQL head:`20260817_525`。live tenant 时 `525 -> 520` 在第一步被 final fence 拒绝且 head 不变;空表已真实运行 `525 -> 520 -> 525` 并确认旧 lifecycle gateway execute 仍为 false;受限 migrator 已真实运行 `480 -> 525`。数据库边界不属于被允许跳过的网络安全监测范围。 - 动态创建的 `NOSUPERUSER,NOCREATEROLE` shared-runtime login 即使设置 alpha GUC 并以 beta payload 调用旧 `tenant_foundation_write` 仍得到 PostgreSQL permission denied;动态 dedicated control login 才能 issue/consume claim。两连接只能消费一个 claim,重启后 replay 拒绝。 - 真实 Flask API 以 server `PRIVATE_SINGLE_TENANT_ID` provision,body 不含 tenant;随后 quota claim、持久 outbox lease、object/graph/cache/index namespace propagation、freeze、status/audit/manifest read、recover、activate、deletion-candidate、rollback、delete 和 delete 后 rollback 拒绝均已在 Docker PostgreSQL 验证。worker 不带显式已派生 scope 或 tenant 已 frozen 时默认拒绝。 - 受限 migrator、OpenAPI、静态与 source/deployment parity 已按上述 fresh 数字复跑;本证据不将本地检查表述为企业验收。 ## 本地工程覆盖与未覆盖 - 已覆盖:服务端派生 private default、持久 membership+route、未批准 shared/SaaS 拒绝、route/spoof/缺 scope 拒绝、真实 Flask RBAC/no-store/closed schema、background durable outbox/worker scope、event envelope、ASCII resource namespace、hash-only/default-disabled manifest、RLS/runtime direct DML、quota atomicity、append-only audit 和完整 lifecycle fence。 - 图、对象存储、缓存和索引只有 namespace contract/攻击 fixture;没有宣称其现有 Neo4j/MinIO/cache/search 实例已获得真实 tenant ACL/partition 隔离。 - keys/connectors/models/plugins/backup/restore/audit export 只有 digest/namespace contract;没有 secret/provider、插件仓库、真实备份恢复或审计导出作业。 - deletion candidate/delete/rollback 的企业审批、legal hold、retention、备份恢复演练和真实外部服务隔离仍须在批准 profile 中完成。 ## 外部门禁 `multi_tenancy` 仍为 `TBD_EXTERNAL`。尚缺批准的 SaaS/共享控制面决策、tenant count、isolation level、capacity/delivery profile、外部 service isolation、backup/restore 目标和 enterprise UAT。任何本地测试通过均不解除这些条件。