SECURITY WHITE PAPER

Sách trắng bảo mật MeshLaw

2026-05-21 v0.1 · dành cho đội ngũ pháp lý và IT xem xét

Tài liệu này tóm tắt các chính sách xử lý dữ liệu, cô lập, mã hóa và kiểm soát truy cập của MeshLaw. Tài liệu dựa trên các sự kiện triển khai thực tế (mã nguồn, migration, cấu hình vận hành), và trong quá trình xác minh hoặc thẩm định (due diligence), chúng tôi sẽ cung cấp kèm các dòng mã liên quan.

1. Cấu trúc hệ thống

Thành phầnCông nghệGhi chú
GatewayMoleculer (Node/Bun) :4098Điểm vào HTTP. Xác thực JWT + tiêm ngữ cảnh RLS
DBPostgreSQL 16 + pgvectorMột instance duy nhất. Cô lập theo team_id bằng RLS
Backend AIvLLM (tự vận hành)Không có luồng đi ra API bên ngoài — dữ liệu vụ việc không rời khỏi hệ thống đến nhà cung cấp LLM bên thứ ba
EmailResend (đã xác minh tên miền)Chỉ dùng cho đăng ký & mật khẩu, không gửi nội dung vụ việc
Push di độngAPNs + FCMChỉ gồm title/body + data — không có nội dung vụ việc

Hosting: khu vực Vultr Seoul — dữ liệu hiện đang lưu trú tại Hàn Quốc; các tùy chọn lưu trú dữ liệu theo khu vực khác có thể cung cấp theo yêu cầu. SSH vận hành: chỉ xác thực bằng khóa (đã tắt mật khẩu).

2. Cô lập giữa các tenant (Tenant isolation)

2.1 PostgreSQL Row-Level Security

Mọi bảng dữ liệu nghiệp vụ đều bật FORCE ROW LEVEL SECURITY:

  • Cô lập trực tiếp (cột team_id): matters, clients, advisories, audit_log, notifications, llm_usage, team_token_quota, messages, device_tokens, stripe_webhook_events, invoice_receipts
  • Cô lập qua JOIN (matter_id → matters.team_id): matter_events, invoices, timesheet_entries, writs, approvals, matter_refs, vault_files, matter_acl, deadlines

Policy: team_id = app_current_team_id() (USING + WITH CHECK). Hàm app_current_team_id() đọc biến GUC của transaction app.team_id.

2.2 Tách vai trò NOSUPERUSER

Gateway vận hành kết nối tới DB bằng role meshlaw_app (NOSUPERUSER · NOBYPASSRLS). Các công cụ phát triển / migration được tách riêng sang một superuser khác — nên không có user BYPASSRLS nào tham gia vào lưu lượng vận hành hàng ngày. Áp dụng từ 2026-05-05.

2.3 Tiêm GUC theo transaction

sql.begin(async (tx) => 
  await tx`select set_config('app.team_id', ${teamId}, true)`
  await tx`select set_config('app.user_id', ${userId}, true)`
  return fn(tx)

Vì dùng SET LOCAL nên giá trị được giải phóng tự động khi transaction kết thúc. 50/50 hành động nghiệp vụ áp dụng lớp bọc này. 7 trường hợp còn lại là các trường hợp raw có chủ đích, như truy vấn password_hash trong auth.signup/login — không có đường rò rỉ dữ liệu.

2.4 Ánh xạ JWT → ctx.meta.user

onBeforeCall của gateway xác minh JWT → tiêm ctx.meta.user = { id, team, role }. Mọi route nghiệp vụ đều nằm trong AUTH_REQUIRED_PREFIXES, nên thiếu token sẽ trả về 401.

2.5 Bảo vệ chống hồi quy (regression)

Việc cô lập tenant được kiểm thử hồi quy trước mỗi lần triển khai tại e2e §7 (RLS):

  • Gọi không xác thực → 401
  • JWT không hợp lệ → 401
  • JWT hợp lệ chỉ truy cập được dữ liệu của chính team đó → 200

3. Bảo vệ thông tin cá nhân (PII)

3.1 Số căn cước / số định danh cá nhân

Lưu trữ: mã hóa bằng pgp_sym_encrypt (BYTEA rrn_encrypted) + 4 chữ số cuối (rrn_last4). Hiển thị: giao diện client bắt buộc che bằng maskRRN()XXXXXX-XXX{last4}. Nếu định dạng không khớp, hàm trả về chuỗi rỗng (ngăn lộ dữ liệu gốc). 8 unit test hồi quy.

3.2 Mật khẩu

Được lưu dưới dạng bcrypt hash. Giao diện client hiển thị trực quan hóa theo thời gian thực dựa trên 4 quy tắc khi nhập (8 ký tự / chữ cái / số / ký tự đặc biệt). Chỉ dùng HTTPS — bản build iOS Release không bật NSAllowsArbitraryLoads.

3.3 Quản lý token

  • JWT: TTL ngắn (mặc định 30 phút), HS256
  • Refresh: xoay vòng (rotation) + phát hiện tái sử dụng. Giá trị plaintext chỉ được gửi cho người dùng một lần; DB chỉ lưu bcrypt hash. Khi phát hiện tái sử dụng, toàn bộ chuỗi token sẽ bị thu hồi

3.4 ACL theo từng vụ việc

Bên cạnh phạm vi team của RLS, có thêm một lớp cô lập theo từng vụ việc (matter_acl). 4 vai trò (owner ⊃ editor ⊃ viewer). Được áp dụng từ messenger v0.1.6 — xem danh sách kênh của một vụ việc cần quyền viewer trở lên, ghi cần quyền editor trở lên.

4. Nhật ký kiểm toán (Audit log)

Các hành động sau được ghi lại tự động trong bảng audit_log:

  • CRUD vụ việc, cấp/thu hồi ACL
  • Phê duyệt/từ chối/yêu cầu chỉnh sửa (status_before/after, comment)
  • Phát hành hóa đơn, biên nhận thanh toán (delta_won, total)
  • Tổng hợp mức sử dụng → hóa đơn/timesheet
  • CRUD tài liệu tham chiếu

Mỗi dòng: actor_name, target_kind, target_id, http_status, matter_id, meta(JSONB), created_at. Được áp dụng RLS — không thể truy vấn bản ghi kiểm toán của tenant khác.

5. Kiểm soát quyền

5.1 Phê duyệt (matter approvals)

Cơ chế bảo vệ theo actor phía server — computeApprovalChainAdvance(steps, status, currentUserId). Chỉ người dùng khớp với approver_id của bước đang hoạt động mới được thao tác. Nếu không khớp, trả về 403 NOT_APPROVER. Cùng một cơ chế bảo vệ áp dụng trên cả desktop và mobile. 7 unit test.

5.2 RBAC (vai trò hệ thống)

users.role_id → bảng roles (admin/partner/associate/staff). auth.invite gán vai trò (chỉ admin mới được cấp).

6. Xử lý dữ liệu

6.1 Gọi mô hình AI

vLLM tự vận hành (mạng nội bộ Tailscale) — không có luồng đi ra API bên ngoài. Nội dung yêu cầu LLM (ngữ cảnh vụ việc, tài liệu) không bao giờ rời khỏi tổ chức. Token gọi và chi phí được ghi lại trong bảng llm_usage (phạm vi team theo RLS).

6.2 Tệp tin (Vault)

  • Lưu trữ: đĩa server (storage_directory được tách riêng theo từng vụ việc)
  • Metadata: bảng vault_files (file_name, mime, size_bytes, text_content)
  • Lập chỉ mục: sau khi trích xuất văn bản, lưu vào text_content → tìm kiếm hợp nhất bằng ⌘K (áp dụng RLS)
  • Đa phương thức PDF: các trang được chuyển sang JPEG bằng mupdf → bộ mã hóa thị giác (vision encoder) của vLLM (không có luồng đi ra bên ngoài)

6.3 Email

Tên miền Resend meshlaw.ai (đã xác minh DKIM/SPF/DMARC). Nội dung: chỉ gồm đăng ký, mời tham gia và đặt lại mật khẩu — không có nội dung vụ việc.

7. Bảo mật hạ tầng

7.1 Truyền tải

Gateway: chỉ dùng HTTPS (Caddy). Cả iOS Release lẫn Android Release đều chỉ dùng URL production (chỉ bản Debug mới dùng localhost).

7.2 Push di động

  • APNs JWT (.p8) — Apple Developer Team ID + Key ID
  • FCM HTTP v1 — file JSON service account của Firebase
  • Nội dung push chỉ là metadata (title/body + gợi ý định tuyến data.type) — không có nội dung vụ việc
  • Token thiết bị: bảng device_tokens (phạm vi team theo RLS)

7.3 Truy cập vận hành

  • Truy cập SSH: xác thực bằng khóa (khuyến nghị cho vận hành)
  • DB: docker-compose chỉ bind vào 127.0.0.1:54322chỉ bind localhost — không lộ ra internet bên ngoài. Chỉ container gateway trên cùng host mới truy cập được (network_mode: host)
  • Sao lưu: /var/backups/meshlaw-db-*.sql.gz (hiện đang thủ công, dự kiến tự động hóa)
  • Bắt buộc sao lưu trước khi áp dụng migration (quy tắc vận hành)

7.4 Thanh toán Stripe

Xác minh chữ ký webhook + cơ chế chống trùng lặp (idempotency guard) (stripe_webhook_events). Dữ liệu thẻ được lưu trong Stripe Vault — chúng tôi không lưu trữ (giảm thiểu phạm vi PCI).

8. Tình trạng tuân thủ (Compliance)

Hạng mụcTrạng thái
Luật Bảo vệ thông tin cá nhân (PIPA, Hàn Quốc)Xử lý theo tiêu chuẩn · DPA cung cấp riêng
ISMS-PĐang xem xét (sẽ thông báo riêng khi nộp hồ sơ)
Nhãn hiệu KISAĐang xem xét
GDPRHiện chưa thuộc phạm vi áp dụng (chưa triển khai tại khu vực EU)

⚠️ ISMS-P / nhãn hiệu KISA hiện đang ở giai đoạn xem xét. Chỉ có thể sử dụng nhãn chứng nhận sau khi đã được cấp.

9. Ứng phó sự cố

9.1 Rò rỉ token

Khi phát hiện tái sử dụng refresh token, toàn bộ chuỗi token của người dùng sẽ tự động bị thu hồi. Gọi /auth/logout hoặc đổi mật khẩu → thu hồi toàn bộ refresh token.

9.2 Lộ dữ liệu

Ngay khi phát hiện, rollback docker-compose lập tức + khôi phục từ bản sao lưu DB.

9.3 Thông báo cho người dùng

Mục tiêu chính sách: thông báo phạm vi ảnh hưởng, các bước khắc phục và hành động cần thiết của người dùng trong vòng 72 giờ (mức khuyến nghị theo Điều 34 PIPA). Hiện chưa có tự động hóa cho quy trình này — khi xảy ra sự cố, người vận hành sẽ tính toán thủ công phạm vi ảnh hưởng và gửi email hàng loạt.

10. Chuyển dữ liệu & xóa dữ liệu

  • Xuất dữ liệu: người dùng có thể xuất dữ liệu của team mình dưới dạng JSON (dự kiến trong v0.2)
  • Xóa dữ liệu: xóa trực tiếp qua giao diện + xóa tài khoản theo yêu cầu qua email → 30 ngày ân hạn → xóa theo tầng (cascade)
  • Thời gian lưu trữ: mặc định lưu vô thời hạn. Nghĩa vụ lưu trữ bắt buộc theo pháp luật (ví dụ: 5 năm theo luật thuế thu nhập) là trách nhiệm của người dùng

11. Yêu cầu xác minh

Nếu quý vị cần xác minh sự kiện hoặc hợp tác thẩm định (due diligence) đối với sách trắng này, vui lòng gửi yêu cầu qua trang liên hệ hoặc email của phụ trách kinh doanh — chúng tôi cung cấp đường dẫn mã nguồn (số dòng) · bản sao migration SQL · kết quả kiểm thử xâm nhập (penetration test, khi đã thực hiện).

Một hộp thư bảo mật chuyên dụng (ví dụ: compliance@meshlaw.ai) sẽ được công bố riêng sau khi hoàn tất xác minh tên miền và chuẩn bị vận hành.


Nếu bạn cần bản PDF để xem xét

Nhấn ⌘P (Mac) / Ctrl+P (Win) và chọn "Save as PDF". Hoặc tải xuống bản Markdown gốc.