Authentication & Access Control
「誰可以使用這個 Bot?」、「不同使用者能用什麼?」 — Auth 與 Access Control 是整合 Asgard Bot Provider 時最早會遇到的議題之一。本指南分層拆解可選方案、各 Pattern 支援程度、以及常見錯誤。
本指南是寫給已完成整合模式 (Pattern) 選型的讀者。你不需要熟悉全部四種模式, 但至少要對其中一個有完整概念, 後續討論才能跟得上。
四種 Pattern 速覽 — 確認你至少熟悉其中一種:
- Pattern 1: Hosted Embed — UI 由 Asgard 托管, 嵌入一個 URL 就能上線
- Pattern 2: Direct Connect — 前端 SDK 直連 Edge Server, 完整客製 UI
- Pattern 3: Workflow Auth — 前端直連 + Workflow 內驗證關卡
- Pattern 4: Backend Relay — 你的後端作為中繼層, 完整掌控
對 Pattern 概念還陌生? → 先回到 總覽與選型 完成選型, 再來看這篇。
為什麼需要這個能力
Bot Provider 預設可在 Asgard 端設定一個 API Key 鎖住存取, 但這只是「最粗粒度」的保護 — 它無法區分個別使用者、無法做動態權限、無法配合你的既有 Auth 系統。
實務上, 你可能會面對以下需求:
- 不想讓 Bot Provider 完全公開, 但也不想讓所有使用者共用同一把 API Key
- 想整合既有的 SSO / OAuth / JWT 系統
- 不同付費等級的使用者能用不同工具集 / 模型
- 法遵需要稽核「誰在何時用了什麼」
不同需求對應不同的實作層級。
三種 Auth 策略與支援模式
Auth 的本質是「在某個你可信賴的位置驗證使用者身份」。可信賴的位置決定了你能做到的 Auth 強度, 也決定了哪些 Pattern 能支援:
| Auth 策略 | 強度 | 支援的整合模式 (Pattern) |
|---|---|---|
| 策略 A: Static API Key | 共享密碼, 所有使用者相同 | Hosted Embed / Direct Connect / Workflow Auth / Backend Relay |
| 策略 B: Dynamic Token Verification | 動態驗證, 可區分使用者 | Workflow Auth / Backend Relay |
| 策略 C: Server-side Session / ACL | 完整 per-user 、 per-resource 授權 | Backend Relay |
想深入理解 Auth 與整合模式的選型關係? → 架構深入解析
Auth 策略選型決策
依照你的情境一路問下去, 終點就是建議使用的 Auth 策略 (可點擊節點前往對應指南):
實作方法
策略 A: Static API Key
此策略是最簡單的方式, 在 Bot Provider 端啟用 API Key, 然後在前端 / iframe URL 帶上即可。所有使用者使用同一把 Key。
設定 Bot Provider API Key
前往 Apps → Integration → 選擇你的 Integration 右上角更多選單 → Edit, 切換 Auth 開關並設定 API Key。
在前端帶入 API Key
若你採用 Hosted Embed, 用 query string 帶入:
<iframe
src="https://embed.asgard-ai.com/ns/your-namespace/bot-provider/your-bot?key=YOUR_API_KEY"
/>
或者在 Bot Provider 端開 Auth 後不在 URL 帶 key, 首次進入會跳密碼框讓使用者輸入。
若你採用 Direct Connect, 透過 SDK 設定:
<Chatbot
config={{
botProviderEndpoint: 'https://api.asgard-ai.com/ns/your-namespace/bot-provider/your-bot',
apiKey: 'YOUR_API_KEY', // 注意:會暴露在前端
}}
/>
適用情境
- POC、Demo
- 對特定圈子分享 Key 的內部小工具
- Agent 本身公開, API Key 主要用於防止濫用(配合 Rate Limit)
不適用情境
- 需要區分使用者身份(誰是誰)
- 需要 per-user 額度 / 配額管理
- 需要法遵稽核
策略 B: Dynamic Token Verification
每則訊息都重新驗證使用者攜帶的 token, 可區分使用者並支援粗粒度授權。依你選的整合模式 (Pattern), 動態驗證有兩種做法:
策略 B-1: Workflow 內驗證
若你採用 Workflow Auth: 前端把 JWT 塞進 payload, Workflow 用 HTTP Request Processor 呼叫你的 Auth API 驗證。
前端:
<Chatbot
config={{
botProviderEndpoint: 'https://api.asgard-ai.com/ns/your-namespace/bot-provider/your-bot',
// Bot Provider 端可以不設 API Key
}}
onBeforeSendMessage={(params) => ({
...params,
payload: {
...params.payload,
jwt: getCurrentUserJwt(),
},
})}
/>
Workflow: 加上 HTTP Request Processor 與 Router Processor 形成驗證關卡。完整範例見 Pattern 3: Workflow Auth。
特性:
- ✅ 不需要建後端
- ✅ Token 為動態, 可整合 SSO
- ❌ 驗證邏輯散落在 Workflow, 複雜化時難維護
- ❌ 無 Server-side Audit Log
策略 B-2: 後端驗證
若你採用 Backend Relay: 請求先進你的後端, 你的後端用任何方式驗證(Session、JWT、OAuth 都行), 驗證通過才轉發到 Edge Server。
前端:
<Chatbot
config={{
botProviderEndpoint: 'https://your-backend.com/api/chat', // 你的後端 endpoint
// 不需要 apiKey,Bot Provider 的 Key 藏在你的後端
}}
/>
後端範例:
- Go
- Node.js
// POST {base}/message/sse — 後端中繼 SSE Relay endpoint;驗證身份後轉發到 Edge Server
func (h *ChatHandler) SendMessage(w http.ResponseWriter, r *http.Request) {
// 1. 驗證使用者(用你的 Auth 系統)
userID, err := h.auth.VerifySession(r)
if err != nil {
http.Error(w, "Unauthorized", 401)
return
}
// 2. 通過後才用 SDK 連到 Edge Server
// (詳見 Pattern 4: Backend Relay 完整範例)
}
// POST {base}/message/sse — 後端中繼 SSE Relay endpoint;驗證身份後轉發到 Edge Server
app.post('/message/sse', async (req, res) => {
// 1. 驗證使用者(用你的 Auth 系統)
let userId: string;
try {
userId = await auth.verifySession(req);
} catch {
res.status(401).send('Unauthorized');
return;
}
// 2. 通過後才用 SDK 連到 Edge Server
// (詳見 Pattern 4: Backend Relay 完整範例)
});
特性:
- ✅ 完全跟你既有 Auth 系統整合
- ✅ Bot Provider API Key 不外洩
- ✅ 後端能集中記錄、稽核
- ⚠️ 需要自行建立後端服務
策略 C: Server-side Session / 細粒度 ACL
僅 Backend Relay 能支援。在你的後端做完整的 per-user / per-resource 授權:
- Go
- Node.js
// 驗證使用者
userID, _ := h.auth.VerifySession(r)
// 取出本次操作要存取的資源
channelID := req.ChannelID
// 細粒度授權:這個 user 對這個 channel 有什麼權限?
permission, err := h.acl.CheckPermission(ctx, userID, "channel", channelID)
if err != nil || !permission.CanSendMessage {
http.Error(w, "Forbidden", 403)
return
}
// 通過才繼續
// 驗證使用者
const userId = await auth.verifySession(req);
// 取出本次操作要存取的資源
const channelId = req.body.channelId as string;
// 細粒度授權:這個 user 對這個 channel 有什麼權限?
const permission = await acl.checkPermission(userId, 'channel', channelId);
if (!permission.canSendMessage) {
res.status(403).send('Forbidden');
return;
}
// 通過才繼續
能達成的進階功能:
- 共享頻道(誰能看、誰能寫)
- 訪客唯讀模式
- 配額管理(本月 user 還剩多少 quota)
- 黑白名單(IP / 地區)
- 不同付費等級綁不同工具集
反模式與常見陷阱
❌ 反模式 1: 把前端的 API Key 當成「身份證」
現象: 「我每個使用者發一把不同的 API Key, 這樣就能 per-user 了!」
問題: API Key 一旦發出去, 使用者可以打開 DevTools 看到自己的 Key, 也可以分享給別人。它根本不是「身份證」, 是「共享密碼」。要 per-user 識別必須用動態 token 並在可信端驗證。
❌ 反模式 2: 用 Workflow Auth 表達複雜 ACL
現象: 在 Workflow 內疊好幾層 HTTP Request + Router, 實作多種 per-resource 權限判斷。
問題: Workflow 是業務邏輯設計工具, 不是 Auth Server。複雜判斷會讓 Workflow 變得難讀難改, 而且每則訊息都要等多支 HTTP API 回應才能繼續。建議: 單純的 yes/no 留在 Workflow, 複雜判斷搬到 Backend Relay。
❌ 反模式 3: 在前端 Payload 帶「使用者 ID」當作識別
現象: 前端把 payload.user_id = '12345' 送進來, Workflow 直接信任這個 ID。
問題: 任何人都能改 user_id, 這等於沒驗證。應採用 策略 B: Dynamic Token Verification 驗證 token, 或透過 策略 C: Server-side Session 由後端直接決定 user_id; 前端送來的身份欄位一律不可信任。
❌ 反模式 4: Bot Provider API Key 寫進前端原始碼然後 commit
現象: apiKey: 'xx-xxx...' 直接 hard-code 在 React 元件裡推上 GitHub。
問題: 即使不是公開 repo, 內部 leak 風險仍高。前端 SDK 即使必須帶 Key(Direct Connect), 也應透過環境變數注入, 並注意這個 Key 終究會被使用者看到。需要保密請使用 Backend Relay。
延伸閱讀
- 完整模式深探: Hosted Embed / Direct Connect / Workflow Auth / Backend Relay
- History 持久化: Conversation History
- 稽核紀錄實作: Audit Logging
- 想深入理解 Auth 與整合架構的關係: 架構深入解析