跳至主要内容

身分驗證與範圍

platform API 使用您組織的 key 進行身分驗證。它有兩種形式 — 相同組織、相同 scopes、不同 runtime:

FormCredentialSent as
Server (backend)kld_sk_live_…Authorization: Bearer …X-Api-Key
Publishable (browser)kld_pk_live_…由 SDK 交換為短期 session;絕不作為 raw bearer 傳送
Authorization: Bearer kld_sk_live_…
# or
X-Api-Key: kld_sk_live_…

Server keys 是您從 backend 在每個 request 中傳送的 bearer。 Publishable keys 用於瀏覽器:SDK 會在 runtime 將其交換為短期、 綁定 origin 的 session token,因此 publishable key 本身不會成為 page source 中持續存在的 credential。直接將 publishable key 當作 bearer 提交會被拒絕 — 請透過 SDK 使用。server key 不會獲得任何 CORS grant,因此頁面永遠無法 讀取 使用它產生的 response — 但 CORS 無法 阻止 request 離開瀏覽器,因此一旦 server key 被放進 page source,它就已經洩漏。API 拒絕它時已經太遲。SDK 正因如此在 mount 時拒絕 kld_sk_… key:請始終將 server key 保留在 server-side。

現有 legacy kld_live_… key 會繼續在兩種情況下作為 direct bearer 使用。

範圍

key 帶有 capability scopes;每個 route family 都需要其中一個:

ScopeRoute familyUsed by
ai/inference-api/b2b/v1/chat/*, /retrieval/*chat embed
design/inference-api/b2b/v1/design/*editor embed
mapsdesigned basemapsthe tile embed
vendor(modifier, not a route)the chat embed, on your own data

預設情況下,Pro/Enterprise key 會使用 aidesignmaps 進行 mint。 Free-plan key 僅限 maps + tile 產品;請參閱 取得 API 金鑰 中的正式 plan × scope × product 表。

Effective admission = stored key × current tier。 Runtime session-exchange 會在每次 call 時重新計算 admission,因此 Pro-tier key 降級為 Free 後, 從那一刻開始只能 mint tile session — 即使 stored key 中仍然 包含 aidesign 限制。rejection subcode 會 區分兩種情況:

  • insufficient_scope — key 從未擁有該 capability。
  • tier_capability_not_allowed — key 曾經擁有,但 current tier 已不再允許。升級 plan 即可恢復。

stored key 中空的 allowed_products 代表所有產品(不是 沒有產品)。tier 仍會將該 superset 收窄至 plan 允許的範圍。

vendor — 有意要求,而且只在真正需要的位置使用

vendor 不是 route gate。它不決定 request 是否被允許;它決定 AI chat 在回答時是否可以查詢您組織上傳的 vendor data。 其他所有 scope 回答的是「這個 key 能否呼叫此 endpoint」;vendor 回答的是「這個 key 能否代表我們的內部資料回答」。

因此它絕不會預設包含 — 請在 mint 時明確要求:

{ "name": "our-site-widget", "scopes": ["ai", "vendor"] }

哪個 key 帶有 vendor,本身就是整個安全決策。 chat embed 是 browser widget:它會將 publishable key 交換為短期 session,因此 vendor-enabled key 必然存在於 public page 中。對於願意展示給所有訪客的資料, 例如 property list、營業時間、公開 rate,這是可以接受的。 對任何不願公開的資訊則不合適。保護 exchange 的 origin allowlist 是 browser convention,而不是 confidentiality boundary: 能自行設定 Origin header 的 caller 不會被它阻擋。

因此:

  • 每個 surface 使用一個 key。 Marketing site、demo page 與 customer-facing app 不應共用同一個 key。只有必須依據您資料回答的 surface 才取得 vendor
  • 絕不要把 rate sheet、cost basis 或任何未公開資訊放在 publishable key 後面。 如果某個回答出現在 public page 上會令人不適合,那些資料就不應放進 vendor-scoped embed。
  • Session 會被限制到其 product,因此即使 parent key 帶有 vendortileviewer session 也絕不會帶有 vendor

如需撤銷,請編輯 key 的 scopes 或 revoke 它 — 兩者都會在 下一個 request 立即生效,包括已經執行中的 session。撤銷不會 延遲到 session expiry。

401 與 403

兩者有意區分:

  • 401 Unauthorized — key 缺少 / 無效 / revoked / expired。重新檢查 key 值並確認未被 revoke。也包括 publishable key 被當作 raw bearer 傳送時的 publishable_requires_session
  • 403 Forbidden — key 存在,但此處不允許使用。常見 subcodes:insufficient_scope(從未擁有)、tier_capability_not_allowed (曾經擁有,但 tier 已不再允許)、session_origin_mismatchip_not_allowed(server keys)、server_key_in_browserproduct_not_allowed

兩者都採用 fail closed:沒有 scopes 的 key 在任何地方都會被拒絕。

Session tokens

SDK 用 publishable key 交換得到的 session 類似:

kld_sess_{env}_{jwt}

例如 kld_sess_live_eyJhbGciOi…。runtime call 中透過 Authorization: BearerX-Api-Key 提交。預設 TTL 為 900 秒(15 分鐘); server 最大值為 30 分鐘。session 會被限制到 mint 時對應的 product, 每個 request 都會重新讀取 parent key 的 live policy。

撤銷會立即生效;新增 grant 則不會。 兩個方向有意 不對稱,並採用 fail closed:

Change to the parent keyEffect on a session already in flight
Revoked or deleted下一個 request 即被拒絕
A scope removed下一個 request 即移除
Plan downgradedtier-gated capability 在下一個 request 被拒絕
Rate limit or monthly cap set to a new value下一個 request 即套用
A scope added, plan upgraded, or a limit lifted entirely不可見 — 需要 mint 新 session

session 只能相對 parent 收窄權限,絕不能擴展超過 mint 時擁有的 scopes, 因此新的 grant 需要新的 exchange。session 很短(預設 15 分鐘),正是為了讓 這個間隔盡量小。

完整 status table 請參閱 Errors