For agentic workers: 本计划只构建可验证的本地工程底座;不得把它表述为已批准的 SaaS、共享控制面、企业 UAT 或生产就绪。
目标: 在不改变默认私有化单租户交付的前提下,提供版本化、服务端派生并在 PostgreSQL 中强制隔离的租户上下文、生命周期、配额、审计和资源命名空间契约。
架构: 请求或后台任务只可从已批准的服务端交付配置/已持久化路由映射获得 TenantContext,永不接受 body/query 自报的 tenant_id。所有 WP10 新的持久化事实由 SECURITY DEFINER 的闭合 JSONB 网关写入,并由 restricted runtime 角色直连 DML 默认拒绝;租户读路径以 RLS 和事务内 dataops.tenant_id 设置进行限制。Neo4j、对象存储、缓存和搜索现有部署没有可验证的原生租户隔离,故只提供严格命名空间适配器、manifest 和攻击测试,实际外部服务隔离仍为 TBD_EXTERNAL。
技术栈: Flask、SQLAlchemy、Alembic、PostgreSQL RLS/SECURITY DEFINER/DB clock、pytest、Docker PostgreSQL。
当前迁移 head 是 20260813_500(20260813_500_runtime_control_claims.py,source/deployment 字节一致)。工作树已有 WP05–WP09 和用户未提交变更,WP10 不重写它们。
| 面向 | 已有可复用覆盖 | WP10 缺口/本计划闭合 |
|---|---|---|
| 身份/权限 | enterprise_identity.py 提供 fail-closed IdP 映射;permissions.py 提供 API 默认拒绝 |
租户域名/路由映射、服务端派生 delivery mode、管理员显式 scope |
| 模型/预算/审计 | WP09 已有部分 tenant_id、DB-time lease/fence、append-only invocation audit |
这些不是全局 tenant model;新增租户注册表、通用配额、tenant audit 和跨服务传播契约 |
| 任务/事件 | 既有 outbox 和 WP05/WP06 任务实现 | 背景任务必须有已验证 tenant scope、冻结时拒绝和事件 envelope 契约 |
| 数据库 | WP06/WP09 使用 owner/runtime 角色与受控网关 | 通用 tenant 表强制 RLS、runtime 无直 DML、闭合 tenant gateway、真实两连接验证 |
| 图/对象/缓存/索引 | 图、知识缓存和 Compose Neo4j/MinIO 现存 | 无可复核的原生多租户隔离;只增加 namespace adapter/manifest/digest/escape 拒绝,外部 service 验证保留 TBD |
| 备份/恢复/插件 | Compose backup 脚本和 WP09 provider contract 已有 | tenant backup/restore/audit-export manifest、approval/hold/fence 及 default-disabled provider 契约;不建设插件仓库 |
tenant_id 或 session GUC 触发写入。dataops_tenant_control identity、持久 membership+route、DB-clock one-shot claim、claim-bound quota/lifecycle、private-only provision、持久 outbox/worker scope lookup、独立 approver fact 与真实签发 API、只读 status/audit/manifest gateway、final downgrade security fence,以及有界 worker fail/retry terminal state。/api/system/tenant/provisions、quota-claims、六个 lifecycle action 以及 status/audit/manifests;全部由 Flask RBAC、no-store、closed schema 和 server-derived identity/route 保护。OpenAPI 同步,shared/SaaS 仍不可激活。20260817_525;独立复验已通过,真实本地验证包括 live-data 525 -> 520 downgrade attack、空库 525 -> 520 -> 525、restricted 480 -> 525、旧 lifecycle gateway 低权拒绝、独立 control/runtime/approver login、两连接 provision/worker race、DB-clock expiry/restart replay、Flask provision/approval/lifecycle/read/outbox 与 quota worker reserve/settle/release。工程状态为 ENGINEERING_BASELINE_COMPLETE_MULTI_TENANCY_ACTIVATION_BLOCKED。文件:
tests/core/system/test_wp10_tenant_context.pyCreate: tests/security/test_wp10_tenant_boundaries.py
[ ] 写失败测试:私有模式只能从 server approved default 解析;共享/saas 未批准时拒绝;请求 payload、后台任务和管理员缺 scope 均拒绝;域名映射、Unicode 同形/路径/URL 逃逸、跨租户 namespace 均拒绝。
[ ] 运行 .venv/bin/pytest tests/core/system/test_wp10_tenant_context.py tests/security/test_wp10_tenant_boundaries.py -q,确认因 WP10 模块不存在而 RED。
文件:
app/core/system/tenant_context.pyapp/core/system/tenant_resources.pyModify: app/core/system/permissions.py
[ ] 仅实现 Task 1 所需最小模型:closed DeliveryMode、TenantContext、服务端 resolver、后台/管理员 scope validator、统一 namespace builder。
[ ] namespace 仅接受 ASCII canonical tenant/resource token;对象、图、缓存、索引、keys、connectors、models、plugins、backup、audit export 均产生不可混用的前缀或 manifest;provider 默认 disabled。
[ ] 重跑 Task 1 测试,确认 GREEN。
文件:
tests/core/system/test_wp10_tenant_lifecycle.pyCreate: tests/integration/test_wp10_tenant_postgres.py
[ ] 覆盖 provision -> active -> frozen -> recovering -> active -> deletion_candidate -> deleted,审批/hold/backup/retention、幂等 replay、changed replay、DB clock lease/fence、冻结任务拒绝、negative/bool/overflow quota 拒绝及跨租户不可借用。
[ ] 真实 PostgreSQL 测试覆盖 low-privilege migrator、runtime direct DML/trigger/owner/SET ROLE 拒绝、RLS cross-tenant read/write 拒绝、two connection single quota winner、gateway audit append-only 与精确 fixture 清理。
[ ] 运行上述两文件,确认其因实现/迁移不存在而 RED。
文件:
migrations/versions/20260817_501_tenant_foundation.pyapp/core/system/tenant_repository.pyapp/core/edge_gateway/runtime_roles.pyMirror: deployment/migrations/versions/20260817_501_tenant_foundation.py, deployment/app/core/system/tenant_repository.py, deployment/app/core/system/tenant_context.py, deployment/app/core/system/tenant_resources.py, deployment/app/core/edge_gateway/runtime_roles.py
[ ] 使用 migration 500 作为唯一 down revision;不修改已应用迁移。创建 owner/runtime roles 的初始化前置检查,Tenant registry/routes/quotas/reservations/lifecycle/audit/manifest 表,并对 tenant-scoped 表 ENABLE/FORCE ROW LEVEL SECURITY。
[ ] runtime 无 direct DML、TRUNCATE、trigger/owner 修改和未经授权 SET ROLE 权限;只可执行 owner 控制的 closed-schema tenant_foundation_write,该函数以 DB clock、advisory lock、lease/fence 和原子 reserve/settle/release 运行。
[ ] 只保存摘要/manifest;拒绝 raw secret、URL/path traversal、Unicode 同形和跨 tenant ref。将 source/deployment 逐字同步。
[ ] 重跑 Task 3 的 unit/integration 测试,确认 GREEN;使用 Docker PostgreSQL 做 500 -> 501 -> 500 -> 501,保留独立连接输出和 head 证据。
文件:
app/api/system/tenant_foundation.pyapp/api/system/__init__.py, app/core/events/outbox.py, docs/architecture/OPENAPI.yamlCreate: tests/test_wp10_tenant_api.py
[ ] 测试先行:认证/既有 RBAC 后的 status/read endpoint 不接收 client tenant id;无 scope/no-store/closed response;事件 envelope 无 tenant scope 被拒绝。
[ ] 添加仅供本地工程验证的最小 status 与 audit/manifest read contract,不开放 SaaS provisioning、真实 key/provider、插件上传或管理 UI。
[ ] 重新生成 OpenAPI(或明确记录无生成差异)并运行 API/事件定向测试。
文件:
docs/architecture/ADR_P3_WP10_HYBRID_DELIVERY.mddocs/runbooks/P3_WP10_TENANT_FOUNDATION_OPERATIONS.mddocs/validation/P3_WP10_FAILURE_INJECTION.jsondocs/validation/P3_WP10_MULTI_TENANCY_EVIDENCE.mdModify: docs/phase3/P3_WP00_REQUIREMENTS.json, docs/DATAOPS_PHASE3_6_MONTH_DEVELOPMENT_PLAN_20260802.md
[ ] 记录 RED/GREEN、真实 PostgreSQL head/round-trip/runtime attack/two-connection/restart-fence、OpenAPI/parity/secret-scan、私有单租户兼容。
[ ] 状态最高为 ENGINEERING_BASELINE_COMPLETE_MULTI_TENANCY_ACTIVATION_BLOCKED;multi_tenancy、SaaS/共享控制面决策、租户数、隔离等级、容量/交付 profile、真实外部 graph/object/cache/index/provider 与企业 UAT/production 均保持 TBD_EXTERNAL。
git diff --check、WP10 scoped secret scan。multi_tenancy = TBD_EXTERNAL,尚缺 SaaS/共享控制面决策、租户数量、隔离等级、容量和混合交付 profile 的书面批准。因此条件包未正式激活。