§3 Phương án A+ + §4 5 Ngoại lệ E1-E5
§3 PHƯƠNG ÁN A+ + §4 5 NGOẠI LỆ E1-E5
Part of: PG Reform Tools — S176 mission Prev: 06-ks3-metadata-shells.md ← | → Next: 08-dot-moi-va-catalog.md Trạng thái: Sơ bộ — sẽ chốt lại trong DESIGN D8 sau khi điều tra xong KS.4-KS.6 + K3-K5
§3. PHƯƠNG ÁN GIẢI QUYẾT — PHƯƠNG ÁN A+ (SƠ BỘ)
Lưu ý: Phương án A đã lộ ra 2 lỗ hổng mới sau KS.1+KS.3. Giữ phương án A làm khung xương chính, nhưng CHƯA chốt cuối — phải đợi điều tra xong KS.4-KS.6 + K3-K5 rồi mới DESIGN tổng. Tránh vá lẻ tẻ.
§3.1 Bản chất phương án A
Dùng PostgreSQL ROLE + PASSWORD AUTHENTICATION (cơ chế chuẩn ngành):
- 1 password DUY NHẤT cho cluster PG, lưu GSM (Google Secret Manager) làm SSOT
- 1 biến
.envCHUNG trên VPS (/opt/incomex/.env, chmod 600, owner root) chứa password - Cả PG container và mọi DOT đọc cùng biến này — đổi GSM 1 lần → kéo về VPS 1 lần → cả hệ thống nhận
- PG REVOKE mọi connection trustless. Mọi connection PHẢI có password đúng.
- DOT đã review code, không sợ nhầm. Mã DOT cứng, không tự đổi ý. Lo ngại chính = chặn ai đó (người, AI, script ngoài) cố ghi PG mà không có thẩm quyền.
§3.2 Tại sao phương án A, KHÔNG phải C (thuần)
Phương án C (Single Function Gateway): Mọi ghi đi qua 1 PG function. Nhưng K1 cho thấy 3 vùng buộc đi thẳng PG (DDL bootstrap không có function tương đương, function call vốn là PG-only, normative tables PG-only). Phương án C thuần chỉ ổn cho DML data, không ổn cho DDL schema.
Phương án A đơn giản hơn, đúng kiến trúc Directus + DOT đang có.
Hạn chế phương án A (sau KS.1+KS.3):
- Hạn chế cũ (K1-K2): Logic dedupe vẫn nằm trong code DOT từng cái → user có password đúng vẫn có thể viết SELECT-then-INSERT sai. Phải kết hợp UNIQUE constraint ở schema.
- (MỚI KS.1) Không có audit DDL ở tầng PG → cần PG event trigger
ddl_command_end+ddl_audit_log+dot-ddl-audit-monitor(bắt buộc bổ sung) - (MỚI KS.3) Registry có "metadata shells" vô hiệu hoá §0-AY → cần PG constraint
file_path NOT NULL+dot-file-path-orphan-check+ CI gate (bắt buộc bổ sung) - (ARGUMENT KS.2 WHY-5) Tuyến L1 qua Directus API là tuyến forensic khả thi DUY NHẤT → nếu giữ phương án A cho cả DDL, cần event trigger tầng PG để không mất forensic trail
Kết luận tạm thời: Phương án A + 2 lớp bổ sung (DDL audit trigger + file_path constraint) = "Phương án A+". Sẽ chốt lại trong DESIGN sau KS.6.
§3.3 Cấu trúc biến môi trường
# /opt/incomex/.env (chmod 600, owner root)
PG_PASSWORD=<lấy từ GSM, không hardcode>
PG_HOST=postgres
PG_PORT=5432
PG_USER_DIRECTUS=workflow_admin # user cho directus DB (Lớp KHO)
PG_USER_AGENT=incomex # user cho incomex_metadata DB (Lớp NÃO)
PG_USER_ADMIN=workflow_admin # superuser cho admin emergency
§3.4 Quy trình rotate password
gcloud secrets versions add pg-password --data-file=- < new_password.txt
gcloud secrets versions access latest --secret=pg-password > /opt/incomex/.env.new
chmod 600 /opt/incomex/.env.new
mv /opt/incomex/.env.new /opt/incomex/.env
docker compose restart postgres
§3.5 DOT đọc password — pattern chuẩn
Bash/Python/Node.js: source/load /opt/incomex/.env → PGPASSWORD env var → connect. Xem Đ33 §14.4.
§3.6 CẤM TUYỆT ĐỐI
- CẤM hardcode password trong code/SQL/YAML/comment
- CẤM commit
.envvào git - CẤM gửi password qua chat
- CẤM dùng password trong URL parameter
- CẤM admin connect bằng tài khoản chung không audit
§3.7 DOT cảnh sát kiểm tra (bổ sung KS.1+KS.3)
dot-pg-credential-audit(A, weekly): quét hardcoded password, git history leakdot-pg-connection-monitor(A, daily): querypg_stat_activityxem connection lạdot-ddl-audit-monitor(A, daily — MỚI KS.1): đọcddl_audit_logbảng mới, alert nếu DDL không có DOT ownerdot-file-path-orphan-check(A, daily — MỚI KS.3): cross-refls dot/bin/vsdot_tools.file_path, alert nếu mismatch
§4. 5 NGOẠI LỆ DOT 100% — HỢP PHÁP HOÁ
Bài học S176: NT3 "DOT 100%" trong HP cũ áp cứng → 3 vùng kỹ thuật + 2 vùng kiến trúc về bản chất KHÔNG THỂ qua Directus REST. Luật cứng quá → người ta bypass → bệnh quay lại. Sửa luật, không sửa hành vi: thừa nhận 5 ngoại lệ HỢP PHÁP, có điều kiện ràng buộc rõ ràng.
§4.1 NGOẠI LỆ KỸ THUẬT (3 ngoại lệ)
E1 — Schema Bootstrap DDL
- Ai:
dot-pg-*-ensure,dot-schema-*-apply - Cách:
docker exec postgres psql - Điều kiện: đăng ký dot_tools, idempotent, có DOT cặp, password GSM, log vào
dot_run_log
E2 — PG Function Call
- Ai: Cron + DOT gọi
SELECT fn_*()trực tiếp - Điều kiện: function
SECURITY DEFINER, cron link tới DOT installer, idempotent, logdot_run_log
E3 — Normative Law Tables (PG-only)
- Ai: Cụm
dot-nrm-* - Điều kiện: domain='normative', pattern an toàn, DOT cặp, password GSM
§4.2 NGOẠI LỆ KIẾN TRÚC (2 ngoại lệ)
E4 — Agent Data → incomex_metadata
- Ai:
pg_store.pyconnect trực tiếp PG - Điều kiện: Agent Data = gateway duy nhất, pattern
ON CONFLICT DO UPDATE, đăng ký dot_tools, password GSM
E5 — Workflow Engine → workflow DB (chưa active)
- Ai: TBD
- Điều kiện: Sẽ định khi engine active
§4.3 KHÔNG HỢP PHÁP — Phải dẹp
Mọi pattern KHÔNG nằm trong E1-E5 = vi phạm NT3, phải dẹp:
- Script ad-hoc psql tay
- CI bypass session variable
- Hardcoded password
- SQL file vĩnh viễn auto-apply không qua DOT
- Writer ghi PG bằng connection không qua GSM
- (KS.3 mới) Writer có metadata trong dot_tools nhưng
file_path=NULL— "metadata shells"
File 07 — §3 Phương án A+ + §4 Ngoại lệ | Index | S176 | Living doc