Kiến trúc LLM gateway đa tenant cho các team
Thiết kế LLM gateway đa tenant với scope team, project key, quota tách biệt, usage log và quyền sở hữu media mà không làm lộ credential.
LLM gateway đa tenant là một control plane cho phép nhiều team, project và application dùng chung một ingress tương thích OpenAI trong khi vẫn tách biệt credential, quota, usage và quyền sở hữu media. Bài toán kiến trúc không phải chỉ là “thêm cột tenant_id”, mà là buộc mọi request trả lời nhất quán bốn câu hỏi: ai đang gọi, ai trả phí, họ được dùng model nào và sau đó được đọc artifact nào. Bài viết này ánh xạ các câu hỏi đó vào những pattern gateway có thể triển khai, gồm team workspace, project-scoped key, rate-limit scope và media isolation cho job ảnh lẫn video.
Vì sao multi-tenancy xuất hiện sau thành công production đầu tiên
Deployment ban đầu thường bắt đầu bằng một admin key và một provider channel. Cách đó hoạt động cho tới khi:
- product, research và support dùng chung một spend pool
- contractor cần quyền truy cập model tạm thời nhưng không được thấy secret của tổ chức
- finance hỏi project nào tạo ra hóa đơn tháng trước
- URL video đã tạo không được phép tải bởi team ngang hàng
- một agent ồn ào làm cạn rate limit của tất cả mọi người
Lúc đó tenancy boundary phải nằm trong gateway, không chỉ trong application code. Soft limit phía ứng dụng vẫn hữu ích, nhưng không thể ngăn key bị lộ hoặc worker cấu hình sai tính phí cho nhầm owner. Một LLM gateway đa nhà cung cấp không có tenant isolation cuối cùng sẽ thành hạ tầng dùng chung với blast radius dùng chung. Hãy đối chiếu với thin reverse proxy trong LLM proxy và AI gateway: proxy chỉ forward; gateway đa tenant còn authorize và account.
Mô hình tenancy cốt lõi: owner, actor và scope
Giữ riêng ba identity trên mọi request:
- Actor — người hoặc service principal khởi tạo call.
- Billing owner — wallet bị trừ quota khi call được settle.
- Access scope — team/project hoặc personal workspace giới hạn key, model và artifact.
Trong hệ thống có hình dạng như repository này, personal token thường tính phí cho user owner, còn team-scoped token gắn cả team lẫn project và resolve billing về team wallet. Middleware phải từ chối team-scoped token khi team workspace bị tắt, project không active hoặc actor thiếu action cần thiết cho project đó. Kiểm tra này phải nằm trên hot path trước channel distribution.
Client / agent
| Bearer sk-...
v
Auth middleware
- resolve token -> user, team_id, project_id, owner_type
- validate membership + project action grants
v
Policy + rate-limit scope
- team:project:user (or personal user scope)
- model allowlists / group grants
v
Relay / task submit
- upstream channel selection
- pre-consume quota against billing owner
v
Usage log + optional media persistence
- store actor, team, project, billing owner
- authorize later content proxy by same scope
Nếu actor và billing owner bị gộp thành một field, bạn không thể phân biệt “ai tiêu ngân sách team” với “ai bấm generate”. Nếu scope chỉ là label trong log, authorization trên /v1/videos/{id}/content sẽ rò rỉ giữa các tenant.
Các bề mặt tenancy phải luôn đồng bộ
1. API key và project binding
Phát hành key như object tenancy hạng nhất:
- personal key cho sandbox cá nhân
- team key gắn với
team_id+project_id - group hoặc model grant tùy chọn để giới hạn stable gateway alias mà key được gọi
Stable alias, chẳng hạn gpt-image-2 hoặc video-default dành cho product, nên ánh xạ tới upstream model ID trong channel configuration. Client giữ nguyên alias; operator xoay raw upstream ID mà không viết lại mọi service. Không bao giờ nhúng upstream provider secret vào client environment. Client chỉ authenticate với gateway; channel giữ provider credential. Áp dụng cùng kỷ luật isolation cho RBAC của quyền truy cập AI API trong sản phẩm nhiều team.
2. Quota và an toàn pre-consume
Billing safety là một vấn đề tenancy. Pre-consume từ billing owner trước công việc tốn kém; settle hoặc refund sau khi upstream hoàn thành. Với media multiplier như image n hoặc video duration, hãy áp hard bound ở validation để client độc hại hoặc có bug không thể làm quota math overflow thành charge âm. Trong codebase này, số ảnh bị giới hạn (MaxImageN = 128) và video duration bị giới hạn (MaxTaskDurationSeconds). Hệ thống đa tenant phải giữ các guard này ở mức global ngay cả khi team policy đặt project budget chặt hơn.
3. Rate limit bằng composite scope key
Scope key hữu ích cho team traffic có dạng team:{id}:project:{id}:user:{id}, còn personal traffic dùng key chỉ theo user. Nhờ vậy agent storm của một project không làm đói chat traffic của project khác. Giữ quyết định limit độc lập với channel selection: team có thể được phép dùng model nhưng vẫn bị throttle.
4. Usage log là bề mặt audit
Mọi call đã settle nên lưu actor, billing owner, team/project nếu có, model alias, request id và media multiplier (n, seconds, size). Finance và security reviewer đều cần các field đó. Usage view hướng product là console surface đã authenticate; public documentation nên giải thích audit model thay vì liên tục link người đọc vào private console route.
5. Quyền sở hữu media không phải metadata tùy chọn
Artifact ảnh và video tồn tại lâu hơn HTTP request. Hãy coi object key và task ID là tài nguyên tenant:
| Surface | Scope trong repository này, hãy verify trước khi tuyên bố | Quy tắc sở hữu |
|---|---|---|
| Image workbench UI/API | Personal/session/token dưới /api/user/image-workbench và các biến thể API-key; object key thuộc user | Hiện không có route image workbench cho team/project |
| Video workbench UI/API | Personal dưới /api/user/video-workbench và team/project dưới /api/teams/:team_id/video-workbench | Team run và asset authorize bằng team + project grant |
| Ingress ảnh tương thích OpenAI | POST /v1/images/generations, POST /v1/images/edits | Tính phí billing owner của token; đừng bịa team history nếu bạn không tự persist |
| Ingress video tương thích OpenAI | POST /v1/videos, retrieve, content; remix vẫn được register | Content GET phải kiểm tra lại cùng owner/scope đã tạo task |
URL của upstream provider thường hết hạn. Gateway persist object vào private storage rồi phục vụ lại qua authorized proxy giúp giảm broken link và public exposure ngoài ý muốn. Khi workbench bắt buộc object storage, hãy fail closed nếu storage cấu hình sai thay vì trả temporary URL không có scope.
Checklist isolation trước khi onboard team thứ hai
Dùng đây làm release gate, không phải slide:
| Boundary | Tiêu chí đạt |
|---|---|
| Auth | Team-scoped token thất bại với member đã bị xóa và project đã disable |
| Billing | Team job không bao giờ trừ personal wallet và ngược lại |
| Models | Project không có grant không thể gọi alias bị hạn chế |
| Logs | Cross-team log query trả empty hoặc denied, không trả một phần row |
| Media | Video content proxy từ chối task ID của team khác bằng not found/forbidden |
| Rate limit | Load của Project A không tiêu token bucket của Project B |
| Admin | Action của super-admin được audit riêng với tenant admin |
Automated test phải đánh vào deny path, không chỉ happy path. Bug đa tenant thường ẩn trong quyết định “soft 404”: trả 404 cho foreign resource thường tốt hơn 403 nếu việc resource tồn tại cũng là thông tin nhạy cảm.
Request path tham chiếu cho chat theo team scope
curl https://your-gateway.example.com/v1/chat/completions \
-H "Authorization: Bearer $TEAM_PROJECT_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "YOUR_STABLE_CHAT_ALIAS",
"messages": [
{"role": "user", "content": "Summarize yesterday deploy risk for project alpha."}
],
"max_tokens": 400
}'
Gateway nên làm nội bộ:
- Authenticate key và resolve
team_id/project_id. - Xác nhận actor được dùng project token cho project đó.
- Resolve model alias qua tập group/channel được phép.
- Pre-consume estimated quota từ team billing owner.
- Relay upstream và ghi consume log có cả actor + owner.
- Expose cùng identifier trong authenticated usage view cho finance và support.
Media dùng cùng quy tắc token nhưng khác scope workbench
Media endpoint không nên tạo hệ auth thứ hai chỉ cho billing. Ưu tiên cùng token và session rule cho ingress tương thích OpenAI:
# Image generation through OpenAI-compatible ingress (GPT Image returns b64_json)
curl https://your-gateway.example.com/v1/images/generations \
-H "Authorization: Bearer $TEAM_PROJECT_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "Product hero shot on matte black pedestal, studio light",
"size": "1024x1024",
"n": 1,
"output_format": "png"
}'
# Async video job (evaluate Sora 2 only with the official deprecation timeline in mind)
curl https://your-gateway.example.com/v1/videos \
-H "Authorization: Bearer $TEAM_PROJECT_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "YOUR_STABLE_VIDEO_ALIAS",
"prompt": "Slow orbit around a ceramic mug on a wood table",
"seconds": "4",
"size": "1280x720"
}'
Scope của các workbench UI khác nhau:
- Image workbench là surface operator cá nhân: preset, run và asset đều theo user scope. Đừng tuyên bố có team image history hoặc route
/api/teams/:team_id/image-workbenchnếu bạn chưa triển khai. - Video workbench hỗ trợ scope personal và team/project. Ánh xạ khả năng generate với manage asset vào team action, đồng thời giữ run history theo project khi session gắn với team.
Endpoint retry-persistence không được chuyển asset sang owner khác. Với video greenfield, hãy ưu tiên vendor và gateway adapter vẫn hỗ trợ được sau khi OpenAI Videos API / Sora 2 đóng vào 2026-09-24 (OpenAI deprecations); nếu vẫn giữ Sora traffic, hãy lập kế hoạch migrate task storage và client code path ngay.
Các lớp policy mở rộng mà không viết lại client
Xếp policy từ thô tới mịn:
- Platform default — image
ntối đa, video seconds tối đa, model bị block. - Team policy — group được phép, budget alert, feature flag.
- Project grant — member nào được generate media hoặc manage video asset.
- Key constraint — IP allow list, expiry, model subset.
- Runtime limit — RPM/TPM và concurrent task cap.
Client tiếp tục gọi /v1/*. Operator đổi policy trong admin configuration và channel model mapping. Đó là lợi ích vận hành của OpenAI-compatible API gateway.
Failure mode riêng của gateway đa tenant
- Silent owner fallback: nếu team resolution thất bại, đừng tính vào personal wallet của actor “cho tiện”. Hãy fail request.
- Shared channel affinity không có isolation label: cache key phải gồm tenant scope, nếu không sticky routing state sẽ bị trộn.
- Giả định image workbench biết team: personal image asset thuộc user không giống team video project.
- Log retention bỏ qua legal boundary: offboarding team có thể cần selective deletion; thiết kế retention job với owner filter.
- Content proxy confusion: dashboard session auth và API token auth đều cần cùng ownership check.
- Budget alert không có action grant: alert finance vô nghĩa nếu member nào cũng có thể mint key.
Security guidance từ OWASP LLM Top 10 vẫn áp dụng: excessive agency, sensitive information disclosure và unbounded consumption trở thành sự cố tenancy khi một tenant ảnh hưởng tenant khác.
Trình tự triển khai tối thiểu
- Model team, project, member và action grant.
- Thêm owner field vào token và consume log.
- Enforce team token validation trong auth middleware.
- Scope rate limit và usage query.
- Chuyển video task authorization và content proxy sang cùng scope helper; giữ image workbench thuộc user trừ khi bạn chủ đích thêm team image persistence.
- Thêm e2e test từ chối cross-tenant cho chat, image byte bạn lưu và video content.
- Chỉ sau đó mới migrate product traffic thật sang team key.
Bỏ deny-path test là cách “có multi-tenant UI” được ship mà không có multi-tenant safety.
Đọc liên quan
Nguồn và đọc thêm
- OWASP Top 10 for LLM Applications
- OpenAI production best practices
- OpenAI deprecations, gồm Videos API / Sora 2 shutdown 2026-09-24
- Google Cloud multi-tenancy guidance for enterprise organizations
Kiểm tra quyết định
Có bắt buộc database riêng cho mỗi tenant không?
Không với phần lớn AI gateway. Row-level isolation cùng query filter nghiêm ngặt là pattern phổ biến. Database riêng giúp regulated isolation hoặc giới hạn storage noisy-neighbor, nhưng nhân đôi migration và channel config. Hãy chọn theo compliance, không theo mốt.
Mỗi microservice có nên mint provider key riêng không?
Không. Mint gateway key theo service identity và giữ provider key trong channel. Điều đó bảo toàn rotation, spend visibility và failover.
Personal workspace cùng tồn tại với team thế nào?
Giữ personal owner type như path hạng nhất. User có thể prototype bằng personal key và personal image workbench, rồi chuyển sang team project key cho shared chat/video spend mà không đổi request shape; chỉ Bearer token và policy thay đổi.
Sai lầm media đa tenant lớn nhất là gì?
Coi upstream result URL là public link bền vững, hoặc giả định mọi workbench đều theo team scope. Hãy persist khi product cần durability, proxy qua authorized route, document expiry khi không thể persist và nói rõ quyền sở hữu personal so với team.
Diễn tập migration
Chọn một production application và migrate từ shared admin key sang team project key. Xác minh consume log có đúng billing owner, foreign video task ID bị từ chối trên /v1/videos/{id}/content, image workbench asset vẫn thuộc user trừ khi bạn xây thêm sharing, và project rate limit không còn va chạm với load test của team ngang hàng.