AgentChat
← 所有文章
安全性·10 分鐘閱讀

如何為每位 SaaS 使用者提供安全且具備租戶感知能力的 AI 代理

使用每次聊天的標頭和現有的授權層,依使用者、工作區或租戶隔離代理操作。

本案例研究將 AgentChat 整合至名為 ProjectDesk 的多租戶專案 SaaS。每位客戶都使用相同的專案與工作 API,但使用者 Alice 只能在 workspace_a 中操作,而使用者 Bob 只能在 workspace_b 中操作。我們會重複使用一份 API 文件,同時建立兩個使用不同僅寫入請求標頭的工作階段。

安全邊界不是一則要求模型留在某個工作區內的提示詞。ProjectDesk 會對每個 HTTP 工具請求進行身分驗證與授權。AgentChat 會選擇操作並注入正確的工作階段憑證;ProjectDesk 則決定每項操作是否獲准執行。

步驟 1:讓商業 API 具備租戶感知能力

GET /v1/projects?status=active
→ { "items": [{ "project_id": "proj_12", "name": "Website launch", "role": "editor" }] }

POST /v1/projects/proj_12/tasks
{ "title": "Review launch checklist", "due_at": "2026-08-28" }
→ { "task_id": "task_91", "project_id": "proj_12", "status": "open" }

ProjectDesk 會驗證承載令牌,從中推導使用者身分,確認其屬於 X-Workspace-ID 工作區,並將該工作區加入每個資料庫查詢中。僅憑專案 ID 絕不能繞過租戶篩選器。讀取範圍和寫入範圍會分別進行檢查。

第 2 步:註冊一個可重複使用的 ProjectDesk 文件

POST $AGENTCHAT_SITE_URL/api/api-documents
Authorization: Bearer ac_live_AGENTCHAT_KEY
Content-Type: application/json

{
  "title": "ProjectDesk Projects and Tasks",
  "description": "List authorized projects and create tasks inside them.",
  "content": "# ProjectDesk API\nBase URL: https://projects.example.com/v1\n\nGET /projects?status=active returns only projects visible to the authenticated workspace member. Response items contain project_id, name, and role.\n\nPOST /projects/{project_id}/tasks body: title required, due_at optional ISO date. Create only after resolving a project through GET /projects. Response contains task_id, project_id, and status.\n\n401 means the session credential is missing or expired. 403 means the current member lacks permission. On either response, do not retry and tell the user that the chat credential or role must be updated."
}

此文件描述的是能力,而不是身分。ProjectDesk 只儲存一次傳回的文件 UUID,並將其附加到每個租戶的聊天中。文件中不會嵌入租戶 ID、使用者令牌或密鑰。

第 3 步:建立 Alice 的 AgentChat 工作階段

POST $AGENTCHAT_SITE_URL/api/agent/sessions
Authorization: Bearer ac_live_AGENTCHAT_KEY
Content-Type: application/json

{
  "title": "ProjectDesk assistant — Alice",
  "llm_config_id": "llm_config_uuid",
  "api_document_ids": ["projectdesk_document_uuid"],
  "system_prompt": "Help the current member manage projects. Never infer access from names; rely on API results.",
  "max_turns": 10,
  "host_headers": [
    { "host": "projects.example.com", "header_key": "Authorization", "header_value": "Bearer alice_short_lived_token" },
    { "host": "projects.example.com", "header_key": "X-Workspace-ID", "header_value": "workspace_a" }
  ]
}

工作階段回應包含一般設定,但絕不會傳回 header_value。AgentChat 可以將 Alice 的令牌注入相符的 HTTP 請求中,而模型既看不到該令牌,也看不到儲存的授權標頭。

第 4 步:使用同一份文件建立 Bob 的工作階段

POST $AGENTCHAT_SITE_URL/api/agent/sessions
Authorization: Bearer ac_live_AGENTCHAT_KEY
Content-Type: application/json

{
  "title": "ProjectDesk assistant — Bob",
  "llm_config_id": "llm_config_uuid",
  "api_document_ids": ["projectdesk_document_uuid"],
  "system_prompt": "Help the current member manage projects. Never infer access from names; rely on API results.",
  "max_turns": 10,
  "host_headers": [
    { "host": "projects.example.com", "header_key": "Authorization", "header_value": "Bearer bob_short_lived_token" },
    { "host": "projects.example.com", "header_key": "X-Workspace-ID", "header_value": "workspace_b" }
  ]
}

API 契約和模型設定可以共用,而工作階段標頭則定義每次對話的呼叫方。如此可避免為每位客戶產生重複文件,並讓憑證輪替獨立於功能文件之外。

步驟 5:在兩個工作階段中執行相同的指示

POST /api/agent/sessions/alice_session_uuid/chat
{ "message": "Create a task called Review launch checklist in the Website launch project, due August 28." }

POST /api/agent/sessions/bob_session_uuid/chat
{ "message": "Create a task called Review launch checklist in the Website launch project, due August 28." }

對 Alice 而言,http_request 只會將 Alice 的權杖和 workspace_a 傳送至 projects.example.com。ProjectDesk 會回傳 Alice 可見的專案;代理程式根據該結果解析出所要求的專案,並張貼工作。Bob 的執行遵循相同的計畫,但 ProjectDesk 會依據 workspace_b 進行篩選。如果 Bob 看不到該專案,代理程式就不會收到相符的專案,因此不得捏造或重複使用 Alice 的專案 ID。

主機比對如何防止憑證外洩

只有當 HTTP 目的地與設定的主機名稱和選用連接埠相符時,AgentChat 才會注入工作階段標頭。每次重新導向跳轉時,系統都會再次進行比對。因此,projects.example.com 的憑證不會被傳送到 files.example.net、圖片主機或意外的重新導向目的地。

重要界線: 主機比對限制了機密資訊的傳送位置。接收請求的 ProjectDesk API 仍必須驗證權杖、工作區成員資格、資源擁有權和操作範圍。

權限失敗的情況

HTTP/1.1 403 Forbidden
Content-Type: application/json

{ "error": "insufficient_scope", "required_scope": "tasks:write" }

AgentChat 的指示會將 401 和 403 視為憑證設定問題。代理程式應停止遭封鎖的操作,並告知使用者需要檢查哪項權限。不應在聊天中要求機密資訊、揭露已儲存的標頭值,也不應針對遭拒絕的要求反覆重試。

ProjectDesk 應確保拒絕回應有用但不包含敏感資訊。它可以說明所需的權限範圍,而無需確認是否存在跨租戶記錄。稽核日誌應記錄已驗證的操作者和嘗試存取的資源,同時對持有者權杖及其他標頭值進行遮蔽。

第 6 步:分別使用 AgentChat 狀態和 ProjectDesk 狀態

GET /api/agent/sessions/alice_session_uuid/messages?after_id=&after_revision=0
GET /api/agent/sessions/alice_session_uuid/state

GET https://projects.example.com/v1/projects/proj_12/tasks

ProjectDesk 聊天介面會輪詢 AgentChat 訊息,並在處理過程中合併助理的修訂內容。執行完成後,專案看板會從 ProjectDesk API 或資料庫重新載入任務。助理回應會說明所執行的動作,但具權威性的產品狀態是已儲存的任務記錄,而不是文字描述。

針對不同的權限層級使用不同的工作階段

唯讀助理可以使用限定為唯讀權限範圍的權杖附加搜尋和報告文件。專案編輯者可以使用具有寫入權限範圍的權杖附加工作撰寫文件。對於變更帳單、刪除帳戶或公開發佈等高風險操作,應使用範圍更窄的工作階段,或使用產品端的待核准端點。

在核准流程中,代理程式會建立一個待處理動作並回傳其 ID。ProjectDesk 會向使用者顯示確切的變更內容,記錄明確的核准,然後在自己的後端執行不可逆的操作。最終的授權決策絕不依賴模型對確認短語的解讀。

正式環境隔離測試

  1. 使用 Alice 的工作階段請求一個已知的 workspace_b 專案 ID,並驗證 ProjectDesk 不會回傳跨租戶資料。
  2. 對 Alice 和 Bob 執行完全相同的提示,並驗證他們的 HTTP 呼叫收到不同的已授權結果。
  3. 分別使每個工作階段權杖過期、撤銷、缺失或損壞,並驗證是否產生正確的 401 行為。
  4. 為成員授予唯讀範圍,並驗證所有工作寫入要求都會返回403,同時不會變更資料庫。
  5. 將請求重新導向至另一個主機名稱,並驗證AgentChat不會轉送已設定的憑證。
  6. 檢查工作階段API回應、工具結果、應用程式記錄和錯誤訊息,確認其中沒有洩漏機密資訊。
  7. 停止並繼續執行,然後驗證恢復的工作仍然只會使用該工作階段的標頭和文件繫結。

可重複使用的多租戶模式

只註冊一次業務能力。為每個使用者對話建立一個AgentChat工作階段。附加相關文件UUID,為確切的API主機注入短期憑證,並在SaaS端點內強制執行身分與原則。接著讓AgentChat管理推理和持久化的對話狀態,同時讓你自己的資料庫繼續作為事實來源。