code-to10 v6 A2: single controlled PG guard entry (code side only)

Postgres audit_ledger append-only guard gains exactly one
execution entry: cloud/ledger_pg_guard.apply_pg_guard, runnable
as 'python3 -m cloud.ledger_pg_guard' (explicit ops command,
not a migration script). It executes PG_GUARD_SQL verbatim from
the constant -- no second copy of the SQL anywhere -- refuses
non-PgConnection targets, does not commit itself (caller/CLI
commits), and refuses with exit 2 on a non-postgres backend so
a no-PG environment can never claim hardening. ensure_schema
still skips PG triggers; POSTGRES_SCHEMA still builds only the
table. Tests lock all of this with a recording fake connection
(no PG execution is faked), a source scan asserting only
ledger.py and ledger_pg_guard.py reference the constant, and
CLI dry-run/refusal cases. Real-PG syntax and UPDATE/DELETE
blocking verification is explicitly left to B5, not claimed here.

(cherry picked from commit b1f6c9158d628186965a9e57576ff8c9500e3f73)
This commit is contained in:
host committed 2026-11-03 02:49:26 +00:00
1 parent 32620c4517
commit 328ffdb7c6
4 files changed
+281 -7

No files matched your search

+5 -3
View File
@@ -334,9 +334,11 @@ Postgres URL)。输出为单 JSON 对象,便于定时任务解析。
- 本机无真实 PG,PG 触发器(`cloud/ledger.py` 的
`PG_GUARD_SQL` 常量)**未在真实 PG 上验证**,沿用 #241
的标注,不在本轨改口称已验证。
- PG 路径的操作流程(生产 PG 须运维手动执行并验证后才认):
1. 在生产 PG 上手动执行 `PG_GUARD_SQL`(函数 + 两触发器),
并实测 UPDATE/DELETE 被拒绝;
- PG 路径的操作流程(生产 PG 须经唯一入口执行并验证后才认):
1. 在生产 PG 上经唯一受控入口
`python3 -m cloud.ledger_pg_guard` 执行护栏(该命令执行的
SQL 即 `PG_GUARD_SQL` 常量本身,不另写一份;除该入口外
无其它执行路径),并实测 UPDATE/DELETE 被拒绝;
2. 经 `GET /admin/audit-ledger/verify`(全局管理员)确认
`ok=true`;
3. 经 `GET /admin/audit-ledger/export` 取导出,用本脚本