Tới nội dung chính
Z-CMS is being built in the open on GitHub. Tham gia cộng đồng

Tất cả bài viết

Multi-tenancy được triển khai trong Z-CMS như thế nào

14 thg 7, 2026 · Z-SOFT Admin · Đọc 4 phút

Một CMS Core phục vụ nhiều website với data isolation xuyên suốt

Multi-tenancy ảnh hưởng đến mọi layer

Multi-tenancy không chỉ là thêm cột tenant_id. Nó ảnh hưởng authentication, authorization, database, cache, storage, queue, search, plugin, theme, logging và billing. Chỉ cần bỏ sót tenant context ở một layer, dữ liệu tenant này có thể xuất hiện trong tenant khác.

Tenant resolution

Z-CMS có thể resolve tenant từ custom domain, subdomain, path hoặc trusted header như X-Tenant-Code. Nếu không xác định được tenant, request bị từ chối trước khi vào business service. Tenant ID không được lấy từ request body do user cung cấp.

Request-scoped tenant context

Sau resolution, tenant context được gắn vào request scope và truyền xuyên suốt service call. Application code dùng tenantContext.getTenantId() thay vì tự parse domain hoặc nhận tenantId tùy ý.

Request
→ Authentication
→ Tenant Resolution
→ Authorization
→ Database / Cache / Storage
→ Queue / Search
→ Plugin / Theme
→ Logging

Database isolation strategy

Z-CMS có thể hỗ trợ shared database/shared schema cho nhiều tenant nhỏ, separate schema cho isolation cao hơn và dedicated database cho enterprise. Application sử dụng cùng repository contract để có thể triển khai hybrid model.

Tenant-aware repository và Row-Level Security

Repository được bind sẵn với tenant hiện tại, giúp developer không phải nhớ thêm WHERE tenant_id ở mỗi query. PostgreSQL Row-Level Security có thể tạo defense-in-depth: ngay cả khi application quên filter, database policy vẫn giới hạn row theo app.tenant_id.

tenant-a:post:123
tenants/tenant-a/media/image.jpg
tenant-a:plugin-seo:settings

Cache, storage, queue và search isolation

Cache key luôn có tenant prefix. Storage API tự thêm path tenants/{tenantId}/... và không cho plugin chọn arbitrary path. Background job mang tenant context. Search query luôn có tenant filter hoặc dùng index riêng cho enterprise.

Authentication, membership và permission

User đăng nhập chưa đồng nghĩa được truy cập mọi tenant. Hệ thống kiểm tra tenant membership trước, sau đó mới kiểm tra role và permission như content.publish. Một user có thể là Owner ở tenant A, Editor ở tenant B và Viewer ở tenant C.

Plugin và theme theo tenant

Mỗi tenant có thể cài plugin, version, settings và active theme khác nhau. Plugin settings được scope theo tenant + plugin ID. Runtime nhận immutable tenant context từ Core, không tự chọn tenant khác.

Logging, rate limit và maintenance

Structured log bao gồm tenantId, requestId, userId và pluginId. Rate limit có thể áp dụng theo IP, user, tenant, API key và plugin. Reindex hoặc migration được chia thành job theo tenant để một tenant không khóa toàn platform.

Testing multi-tenancy

Test luôn tạo ít nhất hai tenant và cố tình dùng resource ID của tenant khác. Security test phải xác nhận repository, cache, storage, queue, search và plugin bridge đều từ chối cross-tenant access.

Kết luận

Z-CMS xác định tenant context từ trusted boundary, giữ context bất biến và enforce nó xuyên suốt Request → Authorization → Database → Cache → Storage → Queue → Search → Plugin → Theme → Logging. Mục tiêu là giúp developer viết feature an toàn mà không phải tự nhớ tenant filter ở từng dòng code.

Key takeaways

  • Security boundary phải được enforce trong Core, không dựa vào thiện chí của plugin.
  • Lifecycle, permission, tenant context và observability là các phần của cùng một platform contract.
  • Developer experience tốt chỉ bền vững khi runtime và supply chain được thiết kế an toàn từ đầu.

GitHub: https://github.com/zscontributor/z-cms
Website: https://z-cms.org