§2.6b KS.1 — INVISIBLE AUDIT GAP
§2.6b KS.1 — 🔴 INVISIBLE AUDIT GAP
Part of: PG Reform Tools — S176 mission Prev: 03-k2-bypass-writers.md ← | → Next: 05-ks2-mar10-debunked.md Khối điều tra: KS.1 (K2 supplement — DDL MySQL era audit) Trạng thái: 🔴 Phát hiện quan trọng nhất của S176 điều tra
Tóm tắt phát hiện
directus_activity chỉ log DDL qua Directus REST API. Mọi DDL chạy trực tiếp psql (CI auto-apply 36 SQL file, dot-pg-*-ensure, dot-schema-taxonomy-pg-apply, dot-schema-*-apply) KHÔNG xuất hiện trong audit log nào. Cộng với PG WAL archive OFF (K0) → cửa sổ 128 ngày directus_activity chỉ cover MỘT PHẦN DDL, phần còn lại MÙ HOÀN TOÀN, không có bất kỳ log nào.
Đây là gốc lý do K0-K2 mất cả buổi mới hiểu được kiến trúc thực tế — không có ai ghi lại lịch sử DDL trực tiếp PG.
Số liệu KS.1 (cửa sổ 96 ngày H2: 2025-12-07 → 2026-03-13)
- 2084 DDL events trên
directus_collections+directus_fields(qua Directus API) - 100% events ghi user
admin@example.com— vi phạm AP-03 ở quy mô 2084 lần (admin monopoly trước S148) - 99.6% là bot/script (Python-urllib 41.8%, node 31.3%, curl 19.4%) — chỉ 0.4% (9 events) qua browser UI thật
- 2 spike đáng chú ý:
- 2026-02-14 05:32-05:48 (16 phút): 490 create + 33 update fields từ 127.0.0.1 — bulk script, ~2 fields/giây
- 2026-03-06 07:03-09:22: tạo collection
meta_catalog+ bulk update 23 collections trong 21 giây — sprint S140 prep migration
- Hint vàng cho KS.2: 2026-03-10 có 41 events từ IP
14.162.130.216(cùng ngàysystem_issues+registry_changelogra đời) directus_relations0 events — không phải bug, là artifact thiết kế Directus (relation quadirectus_fieldsspecial_field)
5 WHY — Cơ hội học gốc rễ
WHY-1 — Admin monopoly legacy
Trước S148, mọi DOT chia sẻ admin token. 2084 events H2 không thể phân biệt "DOT nào sửa schema nào" → khi NT12 yêu cầu writer/verifier khác credential thì dữ liệu lịch sử mất ý nghĩa.
WHY-2 — DOT 100% là codification, không phải start from zero
99.6% DDL là script chứng tỏ triết lý "schema bằng script" đã áp dụng từ H2, mặc dù mốc DOT 100% chính thức là 2026-03-30.
WHY-3 — directus_relations 0 events
Là artifact thiết kế Directus, không phải bug. Audit relation phải qua directus_fields (special_field=m2o).
WHY-4 — INVISIBLE AUDIT GAP (gốc lớn nhất)
Để có SSOT về DDL, phải có DDL event log ở tầng PG (event trigger pg_event_trigger_ddl_commands()) — không thể tin tầng Directus. Hoặc REVOKE quyền DDL khỏi user directus để buộc DDL đi qua 1 cửa.
WHY-5 — Bulk-prep pattern
Mỗi sprint preparation đều là 1-shot bulk (2026-03-06 tạo meta_catalog + 23 collections trong 21s). Nếu fail giữa chừng → không rollback → dữ liệu lệch.
Hệ quả thiết kế cho phương án A
Phương án A (1 password GSM + REVOKE direct + 5 ngoại lệ) chưa đủ chặn lỗ hổng audit. Cần bổ sung:
- PG event trigger
ddl_command_endghi vào bảngddl_audit_logmới — log MỌI DDL bất kể đi qua đường nào - Trigger này SECURITY DEFINER, không thể bypass
- DOT cảnh sát
dot-ddl-audit-monitorquét daily — alert nếu có DDL không có DOT owner - → Sửa Điều 33 §0 hoặc §15 thêm yêu cầu này trong DESIGN tổng sau khi điều tra xong, không vá lẻ tẻ
Chi tiết schema ddl_audit_log + fn_ddl_audit_capture() xem 08-dot-moi-va-catalog.md §5.5.
3 TD phát sinh từ KS.1
| TD | Priority | Mô tả |
|---|---|---|
| TD-S176-DDL-MYSQL-ERA-AUDIT | 🔴 High | INVISIBLE AUDIT GAP. Cần PG event trigger ddl_command_end → ddl_audit_log SECURITY DEFINER + DOT dot-ddl-audit-monitor daily. Bổ sung Đ33 §16 sau DESIGN. |
| TD-S176-ADMIN-MONOPOLY-LEGACY | 🟡 Medium | 2084 events user=admin không phân biệt. K3 verify còn DOT dùng admin token không + backfill nhãn "events <2026-03-30 không phân biệt user". |
| TD-S176-LOG-WITH-SECRET | 🟡 Medium | Rà log file tìm secret leak: /var/log/, /opt/incomex/logs/, Directus logs, agent-data logs, telegram logs. Pattern: password=, token=, Bearer, Incomex2026PG, _secret, api_key. |
File 04 — §2.6b KS.1 | Index | S176 | Living doc