ADR-004: Chính sách Bảo mật Hệ thống (Security Policy)¶
Bối cảnh¶
Hệ thống dx-vas cung cấp dịch vụ cho nhiều trường thành viên khác nhau (multi-tenant), bao gồm nhiều loại người dùng: học sinh, giáo viên, nhân viên, phụ huynh, quản trị viên...
Bảo mật hệ thống không chỉ bao gồm xác thực và phân quyền, mà còn đảm bảo:
- Mỗi tenant được cách ly độc lập
- Không có rò rỉ dữ liệu giữa các tenant
- Dữ liệu nhạy cảm được mã hóa và giám sát truy cập
- JWT và Redis cache được sử dụng an toàn
Quyết định¶
1. Xác thực¶
- Sử dụng Google OAuth2 cho nhân viên & giáo viên
- Sử dụng OTP login (SMS/email) cho phụ huynh và học sinh
- Tất cả xác thực đều đi qua Auth Master hoặc Sub Auth Service (theo từng tenant)
2. Phân quyền động (RBAC)¶
- JWT chứa
user_id,tenant_id,roles - API Gateway sẽ lấy
permissionstừ Redis cache (rbac:{user_id}:{tenant_id}) - Hệ thống đánh giá
conditionđộng dựa trên context của user/request
3. Cách ly Tenant (Tenant Isolation)¶
Hệ thống đảm bảo cách ly tenant ở nhiều cấp độ:
| Lớp | Chi tiết |
|---|---|
| Hạ tầng (GCP) | Mỗi tenant có GCP project riêng (dx-vas-tenant-*), không chia sẻ Cloud Run, Cloud SQL, Secret |
| Mạng | Các service tenant chỉ nhận request từ Gateway hoặc IP danh sách cho phép |
| Dữ liệu | Mỗi tenant có thể có Cloud SQL instance riêng (trong project dx-vas-tenant-* hoặc dx-vas-data). Trường hợp dùng chung instance → phải đảm bảo cách ly bằng schema riêng, hoặc ít nhất các bảng có tenant_id rõ ràng. |
| JWT | Mỗi tenant sử dụng JWT chứa tenant_id, giúp Gateway xác định context chính xác |
| CI/CD | Pipeline tách biệt, không có khả năng cross-deploy giữa tenants |
4. Ranh giới Tin cậy JWT (JWT Trust Boundary)¶
Để đảm bảo an toàn trong xác thực và phân quyền:
- Tất cả JWT đều phải:
- Có chữ ký với secret/key được quản lý bởi Gateway
- Có
tenant_idđể xác định context phân quyền - Gateway là nơi duy nhất tin cậy để đọc & phân tích JWT
- Các service backend (Sub Service, Core Service) không được xử lý trực tiếp RBAC nếu không xác minh JWT qua Gateway
- Tất cả JWT đều có TTL ngắn (dưới 1 giờ), và có thể revoke nếu cần
Nếu cần xác thực giữa các service, phải sử dụng
X-Internal-Callhoặc service token nội bộ có kiểm soát
Hệ quả¶
✅ Ưu điểm:
- Đảm bảo mỗi tenant được cách ly tuyệt đối về dữ liệu, mạng, quyền
- Ngăn chặn tấn công ngang giữa tenant
- Giảm thiểu rủi ro liên quan đến token giả, cache sai context
- Dễ mở rộng mô hình bảo mật theo từng lớp (network, ứng dụng, logic)
⚠️ Lưu ý:
- Việc revoke JWT tức thời cần triển khai thêm token blacklist hoặc short TTL
- Redis cache cần có namespace rõ ràng theo
tenant_id, ví dụ:rbac:{user_id}:{tenant_id}(xem chi tiết trongadr-007-rbac.md)
Liên kết liên quan¶
“Security không phải là một module – mà là mindset toàn hệ thống.”