UDENTIVA Nền tảng Quản lý Nha khoa Thông minh
BẢO MẬT

Mô hình bảo mật API

Với chúng tôi, bảo mật không phải là một lớp thêm vào sau, mà là trung tâm của kiến trúc. Cô lập dữ liệu, tách biệt định danh và ghi idempotent được khắc vào tầng thấp nhất của mã — không phải một tùy chọn có thể tắt, mà là cách hệ thống vận hành.

Cô lập cấp dòng Ghi idempotent Truy vấn có tham số Cô lập loopback
Cô lập dữ liệu

Cô lập cấp dòng — fail-closed

Trên mọi bảng thuộc phạm vi tenant, PostgreSQL Row-Level Security FORCE luôn được bật; chính sách ràng buộc từng dòng theo điều kiện "tenant_id = current_setting('app.current_tenant')".

Một truy vấn đến mà không thiết lập tenant context sẽ trả về không dòng nào — thậm chí không phải lỗi, mà lặng lẽ trống. Việc nhìn thấy dữ liệu của một phòng khám bằng phiên của một phòng khám khác là bất khả về mặt kiến trúc.

Kiểm thử cô lập chéo-tenant bắt buộc luôn xanh trong tích hợp liên tục (CI); nếu đỏ, mã không được hợp nhất.

Ghi nguyên tử (atomic)

Định danh transaction-local, giao dịch nguyên tử

Danh tính tenant được thiết lập ngay từ ĐẦU transaction trong mỗi thao tác ghi và chỉ có hiệu lực trong suốt transaction đó; nó không bám vào connection pool và không rò rỉ sang các yêu cầu khác.

Các giao dịch đa thực thể (hóa đơn + mục + thanh toán + trừ kho) là nguyên tử trong một transaction duy nhất: hoặc ghi tất cả cùng nhau hoặc không ghi gì. Không tạo ra bản ghi dở dang, thiếu nhất quán.

Quyền

Quyền theo vai trò (RBAC) được thực thi trên máy chủ

Kiểm soát quyền được thực hiện ở tầng API; không bao giờ tin vào máy khách hay giao diện trước. Việc ẩn một menu trên trình duyệt chỉ liên quan đến hiển thị — quyết định thật nằm ở máy chủ.

Các thao tác thay đổi ở lõi (Phase 1) được bảo vệ theo các vai trò admin, thư ký và bác sĩ. Ngay cả khi một vai trò không có thẩm quyền gọi endpoint, yêu cầu vẫn bị từ chối.

Chống lặp lại

Ghi idempotent — không giao dịch trùng

Mỗi yêu cầu ghi đều mang một Idempotency-Key; khóa phía máy chủ chặn giao dịch thứ hai đến với cùng một khóa.

Ngay cả khi mạng bị ngắt hoặc máy khách gửi lại cùng một yêu cầu, sẽ không có khoản thu hay hóa đơn thứ hai nào được tạo. Kết quả luôn duy nhất và có thể dự đoán.

Bảo mật truy vấn

SQL injection là bất khả — truy vấn có tham số

Mọi truy vấn cơ sở dữ liệu đều là các câu lệnh hoàn toàn có tham số, được sqlc tạo ra tại thời điểm biên dịch. Trong toàn bộ mã nguồn không có lấy một dòng nào tự dựng SQL bằng cách nối chuỗi thủ công với đầu vào của người dùng.

Điều này loại bỏ về mặt cấu trúc cả một lớp tấn công SQL injection — nó dựa vào cách câu truy vấn được xây dựng, chứ không phải vào nỗ lực "lọc" hay "thoát ký tự".

Bề mặt mạng

Cô lập loopback — lõi đóng với bên ngoài

API lõi chỉ lắng nghe trên 127.0.0.1 (loopback). Mọi nỗ lực gắn vào 0.0.0.0 hoặc một IP công khai đều bị từ chối ngay khi khởi động; lõi không bao giờ được mở ra Internet trong bất kỳ trường hợp nào.

Bề mặt công khai duy nhất là một cổng mỏng (BFF): nó không giữ nghiệp vụ ngoài phiên đăng nhập, render và CSRF. Trình duyệt không bao giờ có thể nhìn thấy hay định địa chỉ trực tiếp tới API lõi.

Định danh & phiên

Mật khẩu argon2id, khóa phiên opaque

Mật khẩu được hash bằng argon2id, một thuật toán chuẩn ngành và khó tấn công qua bộ nhớ; không dùng hash thô hay yếu.

Khóa phiên là các giá trị opaque ngẫu nhiên mật mã dài 32 byte, được lưu trong Redis và hết hạn theo TTL. Trình duyệt chỉ nhận được cookie HttpOnly + Secure + SameSite; khóa không bao giờ được để lộ ra JavaScript.

Kiểm toán

Nhật ký kiểm toán không thể thay đổi (chỉ ghi thêm)

Các thao tác quan trọng được ghi vào nhật ký kiểm toán chỉ-ghi-thêm trong CÙNG một transaction với thao tác thay đổi kích hoạt chúng. Nếu giao dịch bị hoàn tác thì nhật ký kiểm toán cũng không được ghi — hai điều này không thể tách rời.

Quyền UPDATE/DELETE trên bảng kiểm toán đã bị thu hồi; các bản ghi không thể chỉnh sửa hay xóa về sau. Lịch sử giữ nguyên như nó vốn có.

Privacy

Che dữ liệu nhạy cảm

TCKN, mật khẩu, khóa phiên và dữ liệu y tế không lọt vào nhật ký dưới bất kỳ hình thức nào. Ngay cả trong kết quả gỡ lỗi, các trường này cũng được che.

Khi cần, các trường nhạy cảm được mã hóa ở cấp cột. Dữ liệu y tế nhạy cảm được bảo vệ bằng các quy tắc được đặt vào ngay từ đầu trong thiết kế.

Toàn vẹn Tiền tệ

Bảo mật tiền tệ — numeric, bút toán đảo

Tiền được lưu ở mọi nơi bằng numeric(14,2); không tính toán tiền bằng float. Việc làm tròn diễn ra tại một điểm duy nhất, trên máy chủ — không xảy ra lệch xu hay sai số làm tròn.

Hủy và hoàn tiền được xử lý bằng một bút toán đảo thay vì xóa bản ghi. Số dư công nợ không được nhập thủ công; luôn được suy ra từ tổng hóa đơn và thanh toán. Lịch sử không bị phá vỡ.

Chuyển giao

Bảo mật truyền tải & trình duyệt

Toàn bộ lưu lượng được truyền qua HTTPS/TLS và HSTS được bật; trình duyệt chỉ thiết lập kết nối ở dạng mã hóa.

Chính sách bảo mật nội dung (CSP) nghiêm ngặt chặn inline script; X-Frame-Options DENY ngăn clickjacking, X-Content-Type-Options nosniff ngăn nhầm lẫn kiểu MIME. Referrer-Policy và Permissions-Policy cũng được áp dụng.

Quan trọng

Tách biệt tier danh tính + mặt phẳng quản trị riêng

Người dùng phòng khám, cổng thông tin bệnh nhân và nhà vận hành nền tảng là các tier danh tính RIÊNG BIỆT: tiêu đề riêng, không gian phiên riêng. Khóa của một tier không hoạt động ở tier khác — ranh giới quyền được tách bạch tuyệt đối.

Các điểm cuối nền tảng và quản trị (cấp phát tenant, lập hóa đơn, quản lý tự động hóa/tiện ích, tạo API key) KHÔNG NẰM trong public API.

Các chức năng này chạy trên một mặt phẳng điều khiển riêng biệt, nội bộ, có mẫu định danh khác (khóa quản trị chuyên biệt); không thể truy cập và không thể phát hiện từ bên ngoài. Nhờ đó, bề mặt tấn công giảm đi rõ rệt.

CÁCH HOẠT ĐỘNG

Một transaction, cô lập fail-closed

Luồng khái niệm dưới đây minh họa cách mỗi thao tác ghi được khóa vào tenant và giữ tính idempotent. Chỉ nhằm mục đích diễn giải.

# 1) Tenant context được thiết lập ngay từ ĐẦU transaction (chỉ riêng cho tx này)
BEGIN;
  SELECT set_config('app.current_tenant', :session_tenant_id, true);

  # 2) Khóa Idempotency-Key — cùng một khóa sẽ không tạo giao dịch thứ hai
  SELECT lock_idempotency(:idempotency_key);

  # 3) Ghi đa thực thể — tất cả đều nguyên tử trong một tx duy nhất
  INSERT INTO invoices  ...;   # RLS: tenant_id tự động bao gồm
  INSERT INTO payments  ...;
  INSERT INTO audit_log ...;   # append-only, cùng một tx
COMMIT;

# Nếu context không được thiết lập, chính sách RLS sẽ không trả về dòng nào:
SELECT * FROM patients;  --> 0 dòng (không phải lỗi, lặng lẽ trống)
Có thể kiểm chứng độc lập

Một phần bảo mật truyền tải có thể quan sát được từ bên ngoài: bạn có thể tự kiểm tra chứng chỉ HTTPS/TLS của kết nối, cùng các tiêu đề bảo mật phản hồi như HSTS và chính sách bảo mật nội dung, ngay trong công cụ phát triển của trình duyệt. Các tuyên bố của chúng tôi dựa trên kiểm soát kiến trúc, không phải câu chữ tiếp thị.

Bạn có câu hỏi về kiến trúc bảo mật?
Đội ngũ của chúng tôi rất vui được trao đổi cùng bạn về các chi tiết kỹ thuật và yêu cầu tuân thủ của bạn.
Liên hệ