跳至主要內容

直通受管 ID

當您使用 LiteLLM 的 passthrough 端點(例如 /openai_passthrough/v1/files、/azure/openai/batches)時,上游提供者會回傳其自己的原始 ID,例如 file-abc123 或 batch_xyz。預設情況下,這些 ID 會直接回傳給您的用戶端,這表示:

  • 任何猜到或攔截到其他使用者 file-abc123 的人都可以使用它。
  • 您在 proxy 層級沒有任何誰擁有什麼的紀錄。
  • 多租戶隔離必須完全在您的應用程式程式碼中完成。

Passthrough Managed IDs 可解決這個問題。啟用此功能後,proxy 會:

  1. 產生 一個穩定、不可讀的 managed ID,對應它在回應中看到的每個原始提供者 ID。
  2. 儲存 managed_id → raw_id 對應關係到 proxy 資料庫,並標記建立它的使用者/團隊。
  3. 在將任何請求轉送上游之前,先進行擁有權/權限檢查,然後將 managed ID 解析 回原始提供者 ID。

即使使用者猜到或偽造一個 managed ID 字串,您的用戶端也永遠看不到原始提供者 ID,也永遠無法存取不屬於自己的資源。

如何啟用​

在您的 proxy 設定中,將一行加入 general_settings:

general_settings:
passthrough_managed_object_ids: true

此功能需要:

  • 已為 proxy 設定資料庫(Prisma / PostgreSQL)。
  • 可用的 managed_files enterprise hook。

此功能僅對 OpenAI(/openai_passthrough/...)與 Azure OpenAI(/azure/openai/...)的 passthrough 路由生效。

/openai/v1/files、/openai/v1/batches 和 /openai/v1/responses 不是 passthrough 路由

這三個路徑由 LiteLLM 的原生端點提供服務,完全像 /v1/files、/v1/batches 和 /v1/responses 一樣,因此 passthrough_managed_object_ids 永遠看不到它們。若要在這裡隔離租戶,請將 require_managed_files 用於檔案與批次,並使用內建的 Responses API 擁有權檢查來處理回應。OpenAI 的 passthrough 前綴是 /openai_passthrough。

原生受管端點與直通模式​

原生 managed 端點具有 managed ID 的 passthrough
URL 前綴/v1/files、/v1/batches/openai_passthrough/v1/files、/azure/openai/batches
路由LiteLLM 內部邏輯;基於模型的路由直接轉送至上游提供者
憑證解析透過 model_list router透過 PassthroughEndpointRouter / 環境變數
適用情境您希望 LiteLLM 自動選擇正確的 deployment,或您需要跨提供者批次處理您想直接呼叫提供者 API(例如微調、responses、自訂端點),但仍需要 proxy 層級的存取控制
ID 管理一律由 LiteLLM 管理僅在 passthrough_managed_object_ids: true 時由 managed IDs 管理
串流 ID 產生支援支援 POST /v1/responses 搭配 stream: true(每個事件中的 response.id 都會被重寫)

支援的端點​

回應 ID 鑄造(OUTPUT)​

以下是 LiteLLM 會針對其在回應本文中看到的原始提供者 ID 產生 managed ID,並在回傳給用戶端之前替換掉它們的特定路由。

提供者方法路徑重寫的欄位
OpenAIPOST/v1/filesid(file-)
OpenAIGET/v1/files/{file_id}id(file-)
OpenAIDELETE/v1/files/{file_id}id(file-)
OpenAIPOST/v1/batchesid(batch_)、input_file_id、output_file_id、error_file_id
OpenAIGET/v1/batches/{batch_id}id(batch_)、input_file_id、output_file_id、error_file_id
OpenAIPOST/v1/batches/{batch_id}/cancelid(batch_)、input_file_id、output_file_id、error_file_id
OpenAIPOST/v1/responsesid(resp_)
OpenAIGET/v1/responses/{response_id}id(resp_)
OpenAIDELETE/v1/responses/{response_id}id(resp_)
AzurePOST/v1/filesid(file-)
AzureGET/v1/files/{file_id}id(file-)
AzureDELETE/v1/files/{file_id}id(file-)
AzurePOST/v1/batchesid(batch_)、input_file_id、output_file_id、error_file_id
AzureGET/v1/batches/{batch_id}id(batch_)、input_file_id、output_file_id、error_file_id
AzurePOST/v1/batches/{batch_id}/cancelid(batch_)、input_file_id、output_file_id、error_file_id
AzurePOST/v1/responsesid(resp_)
AzureGET/v1/responses/{response_id}id(resp_)
AzureDELETE/v1/responses/{response_id}id(resp_)

POST /v1/responses 搭配 stream: true 也一樣適用。proxy 會從第一個 response.created 事件起就將回應記錄為呼叫者自己的回應,並在串流轉送時將每個事件中的 response.id 重寫,因此串流回應的擁有與保護方式與非串流回應完全相同。

受管 ID 解析(INPUT)​

這不依路由而定。對每一個 OpenAI 或 Azure passthrough 請求,LiteLLM 在轉送上游之前都會掃描整個請求:

位置掃描內容
URL path每個 path segment
Query params每個字串型別參數
Request body所有字串值,遞迴掃描(可用於巢狀物件與陣列)

這表示任何在 path、query 或 body 中接受檔案 ID、批次 ID 或回應 ID 的端點,都會自動解析 managed ID,包括上方輸出表格中未列出的端點,例如微調工作(/v1/fine_tuning/jobs)、assistants,或任何自訂端點。

範例,微調工作:

# Client sends managed IDs for training_file and validation_file
response = client.post("/azure/openai/v1/fine_tuning/jobs", json={
"model": "gpt-4o-mini",
"training_file": "bGl0ZWxsbV9wcm94eTpwYXNzdGhyb3VnaDtwcm92...", # managed ID
"validation_file": "bGl0ZWxsbV9wcm94eTpwYXNzdGhyb3VnaDtwcm92...", # managed ID
})

# Proxy resolves both to raw file IDs and forwards:
# POST .../fine_tuning/jobs
# { "model": "gpt-4o-mini", "training_file": "file-2dbc75...", "validation_file": "file-2dbc75..." }

請求流程 - 任一端點​

這適用於任何 OpenAI 或 Azure passthrough 端點,不只微調。相同的 path/query/body 掃描會在每個請求上執行;下方範例使用的是 body 中含有 managed file ID 的微調工作。

在回應路徑上,rewrite_response_ids() 會為原始提供者 ID 產生 managed ID,但只限於輸出對應表中列出的路由(files、batches、responses)。其他端點(例如微調)會原樣回傳上游 ID,除非它們出現在該對應表中。

權限檢查​

每次 managed ID 解析都會依序執行四項檢查。全部都必須通過,否則請求會被拒絕。

1. 提供者比對​

managed ID 會編碼其鑄造時所對應的提供者(例如 azure)。如果您在 OpenAI passthrough 路由上送出 Azure 鑄造的 ID(反之亦然),proxy 會回傳 404,並且絕不會將該 ID 轉送到上游。

2. 資料庫存在性​

managed ID 必須對應到 proxy 資料庫中的真實資料列。猜測、偽造或以 base64 構造的字串,只要不對應到真實資料列,就會回傳 404。當 DB 檢查失敗時,原始提供者 ID 絕不會被轉送到上游。

3. 存取檢查 - 每次請求​

can_access_resource() 會決定呼叫者是否可使用特定資源:

呼叫者身分在以下情況授予存取權
Proxy 管理員 / master key一律
擁有 user_idcreated_by == user_id
擁有 team_id(service account)team_id == resource.team_id
同時擁有 user_id 和 team_id上述任一條件
兩者皆無從不(403)

4. 存取檢查 - 列出端點​

build_owner_filter() 會為列表操作限制資料庫查詢範圍(見下方)。相同規則以 Prisma WHERE 子句表示如下:

呼叫者WHERE 子句
Proxy 管理員 / master key{}(無篩選條件 — 可看見所有資料列)
僅 user_idcreated_by = user_id
僅 team_idteam_id = team_id
同時擁有 user_id 和 team_idcreated_by = user_id OR team_id = team_id
兩者皆無立即回傳空清單 — 不進行 DB 查詢

列出端點的運作方式​

GET /openai_passthrough/v1/files 和 GET /openai_passthrough/v1/batches(以及它們的 Azure 對應項目)會被完全攔截。請求不會被轉送到上游提供者。相反地,proxy 會查詢自己的資料庫,並且只回傳呼叫者擁有的資料列:

GET /openai_passthrough/v1/files
┌─────────────────────────────┐
admin key? │ WHERE {} │
│ (all rows) │
└─────────────────────────────┘
user key? ┌─────────────────────────────┐
│ WHERE created_by = user_id │
│ OR team_id = team_id │
└─────────────────────────────┘
│
▼
OpenAI-style paginated response
{ "object": "list", "data": [...] }
All IDs in data[] are managed IDs

支援分頁參數 limit、after 和 before,並且會直接對應到 created_at 上的游標。

沒有 user_id 且沒有 team_id 的呼叫者一律只會收到空清單;proxy 絕不會退回到未限定範圍的查詢。

代理程式從未看過的物件​

當物件是透過已啟用此功能的 passthrough 路由建立時,系統會記錄其擁有權。在您啟用之前建立的檔案、批次或回應,或是直接以相同 API 金鑰在提供者端建立的物件,在 proxy 端都沒有擁有者,因此任何被允許使用 passthrough 路由的金鑰,仍可透過其原始提供者 ID 存取它(請見下方限制)。LiteLLM 會刻意不嘗試替任何人認領這些物件。

如果這些既有物件也必須被隔離,嚴格的做法是停止讓多個租戶共用同一組提供者金鑰:為每個團隊定義一個 自訂 passthrough endpoint,每個 endpoint 的 headers 都帶有該團隊自己的提供者 API 金鑰,並在團隊的 metadata 中使用 allowed_passthrough_routes 將每個團隊限制到其對應的 endpoint。如此一來,提供者本身會管理可見性,而 managed ID 仍可在其上正常運作。

限制​

串流僅會針對回應重新寫入​

POST /v1/responses 串流是唯一會攜帶可鑄造 ID 的 SSE 回應,因此也是 proxy 唯一會重寫的串流。其他所有串流 passthrough 回應都會原封不動地轉送。

原始 ID 僅對其擁有者有效​

如果您送出的是原始提供者 ID(例如 file-abc123)而不是 managed ID,proxy 會先檢查它是否屬於受管理資源,再決定是否轉送。若原始 ID 對應到其他呼叫者的資源,會以 404 拒絕(與未知的 managed ID 相同,讓呼叫者無法探測哪些 ID 存在)。擁有者自己的原始 ID 會被轉送。proxy 從未記錄過的原始 ID 會在不進行擁有權檢查的情況下被轉送,這也是上述物件可被存取的原因。

ID 以提供者為範圍​

為 azure 鑄造的 managed ID 不能用在 openai passthrough 路由上,反之亦然。嘗試這麼做會回傳 404。