36 lines
5.9 KiB
Markdown
36 lines
5.9 KiB
Markdown
# Provider API v1
|
||
|
||
Platform identity и provider identity независимы. Все операции требуют текущего actor и tenant; запрос к provider mode допускается только если матрица разрешает local/on_prem/managed_remote. Provider broker — модуль Platform API для управляемых credentials, локальный аналог — sidecar; provider plugin вызывается в изолированном host, а не внутри API-процесса.
|
||
|
||
| Метод и путь | Запрос | Ответ |
|
||
|---|---|---|
|
||
| GET /v1/providers | deploymentMode | 200 {items:[ProviderDescriptor]} |
|
||
| POST /v1/provider-auth-flows | providerId, methodId, placement, returnRoute | 201 AuthFlow |
|
||
| GET /v1/provider-auth-flows/{id} | — | 200 AuthFlow с текущим status |
|
||
| DELETE /v1/provider-auth-flows/{id} | — | 204, flow cancelled |
|
||
| GET /v1/provider-auth/callback/{providerId} | state, code или error | 303 на allowlisted внутренний returnRoute |
|
||
| GET /v1/connections/{id} | — | 200 ConnectionSummary |
|
||
| POST /v1/connections/{id}/verify | — | 200 {status, capabilities, checkedAt} |
|
||
| GET /v1/connections/{id}/models | cursor, limit | 200 Page<ModelDescriptor> |
|
||
| DELETE /v1/connections/{id} | — | 204 после платформенного revoke; remote revoke best effort с аудитом |
|
||
|
||
ProviderDescriptor: id, pluginVersionId, methods:[{id, kind:api_key/oauth_pkce/device_code/official_client, allowedPlacements, status:enabled/gated/unsupported, reason?}], capabilitiesRevision. methodId определяется provider adapter; браузер не выбирает произвольный OAuth endpoint.
|
||
|
||
AuthFlow: id, providerId, methodId, status:pending/connected/failed/expired/cancelled, expiresAt, action:{type:open_url/device_code/local_client, url?, userCode?, intervalSeconds?}, connectionId?. PKCE verifier, refresh token и client secret не возвращаются клиенту. returnRoute — относительный allowlisted путь. API-key создаётся через защищённый POST /v1/connections, описанный ниже, не через GET callback.
|
||
|
||
ConnectionSummary: id, tenantId, ownerId, providerId, pluginVersionId, authMode, placement, bindingId?, status:active/reauth_required/revoked/error, scopes, accountLabel, expiresAt?, capabilitiesRevision. bindingId для runner_private_store привязывает к одному разрешённому пулу/пользовательскому окружению. Verify не выполняет платный inference без отдельного opt-in; model list не гарантирует entitlement.
|
||
|
||
POST auth flow и verify принимают Idempotency-Key. OAuth callback одноразовый, проверяет state, expiry, actor binding и exact redirect URI; при потере пользовательской сессии завершение требует reauth владельца. Device polling выполняет broker по interval, не каждая открытая вкладка. Authentication errors возвращаются нормализованно без raw provider token response.
|
||
|
||
## Инференс как внутренний контракт
|
||
|
||
ProviderInvocation: invocationId, runId, attemptId, connectionId, modelId, request, deadlineAt, capabilityRequirements. Доступ проверяется по executionToken и активному lease. Обёртка DSH нормализует stream events, usageStatus и terminal outcome. Credentials доступны только разрешённому adapter/официальному клиенту; shared глобального аккаунта нет. Внешний provider request id сохраняется для диагностики и дедупликации, если API поддерживает её.
|
||
|
||
## Передача API key
|
||
|
||
POST /v1/connections принимает {providerId, methodId, placement, label, credentialInput?, bindingId?}; ответ 201 ConnectionSummary. Для server_vault credentialInput={apiKey:string} передаётся только в TLS body, исключается из access/error logs, tracing и сохранения idempotency payload; сервер хранит только хеш запроса и зашифрованный ключ. Для local_keychain/runner_private_store ключ принимает локальный broker, облачный API получает только подтверждённый bindingId. Переданный клиентом bindingId проверяется на владельца и proof-of-possession от доверенного broker. API не принимает локальный путь к чужому файлу или произвольный vault URI.
|
||
|
||
GET /v1/connections принимает cursor/limit и возвращает Page<ConnectionSummary>. ModelDescriptor: id, providerId, displayName, capabilities, contextWindow?, availability:unknown/available/unavailable, checkedAt?. Поля capabilities — набор поддержанных операций (text, tools, image_input, structured_output), а не гарантия доступа к модели по подписке.
|
||
|
||
AuthFlow создаётся только для oauth_pkce/device_code/official_client. Callback OAuth использует GET только для провайдеров с query response mode; иной response mode требует отдельного адаптера и conformance. По истечении expiresAt flow больше не может создавать connection. Внешний callback без пользовательской cookie проверяет flow binding, а выдача connection пользователю требует исходную сессию либо повторный вход владельца.
|