forked from wangziqi/gongxue-base
1.9 KiB
1.9 KiB
租户外键完整性审计
目的
RLS 负责控制一行是否可见,但不能保证一条租户内记录引用的父记录也属于同一租户。历史 schema 仍有一批只引用父表 id 的外键,因此上线门禁同时执行:
- 快速 schema 指纹:生产 readiness 查询
pg_catalog,发现新增、删除、改名、未验证的租户间外键即阻断。 - 完整数据审计:只在
local、test、ci隔离克隆库执行,逐条检查现有数据是否满足租户不变量并输出 JSON 证据。
默认规则是子表与父表 tenant_id 必须一致。当前只有三个显式例外:
- 平台审计规则允许
tenant_id is null,代表全局规则;租户专属规则必须与告警租户一致。 - 租户采用公共题库时,源题库可以属于平台租户,但必须是
source_scope='platform'。 - 公共题库通知可以指向平台源题库,同样必须是
source_scope='platform'。
新增例外必须同时补业务理由、查询不变量、合同测试和 schema 指纹。不得只更新指纹跳过审计。
执行
隔离库必须已应用全部迁移,并在 app_private.environment_safety 标记为 local/test/ci 且 allow_destructive_tests=true。该命令只读,但会扫描相关业务表,因此沿用破坏性测试确认口令,防止误连生产主库:
DATABASE_URL='postgresql://postgres:postgres@127.0.0.1:55432/postgres' \
node scripts/tenant-foreign-key-audit.js \
--confirm=SMOKE_SEED_LOCAL_OR_CI_ONLY \
--write=docs/refactor/launch-artifacts/tenant-foreign-key-audit.json
通过条件:
schema.schemaMatches=trueschema.unvalidatedRelations=[]data.auditedRelations等于指纹关系数data.invalidRelations=0status=pass
生成的 JSON 及 SHA-256 需要写入 production-launch-evidence.json 的 db.tenant-foreign-key-audit 检查项。