Главная/Resolve/Цепочка resolve ENУКРРУС API-справочник (ReDoc) ↗

Цепочка resolve

USER → ORGANIZATION → PLATFORM — как рантайм получает тот единственный ключ, которым должен работать, вместе с plaintext.

POST /internal/v1/credentials/resolve — это то, что рантаймы перевода вызывают перед каждой задачей: дай мне credential для пользователя X, провайдера P. Это эндпоинт сервисной плоскости, требующий scope provider-credentials.invoke (Service Plane Tokens) — и, вместе с reveal, одно из всего двух мест, где plaintext покидает сервис.

Запрос

{
  "user_id": "b6a4f6cd-…",
  "org_id": "0d1e2f3a-…",
  "provider_code": "deepl_api",
  "purpose": "translation",
  "allow_platform_fallback": true,
  "correlation_id": "req-01J8…"
}

user_id и org_id должны происходить из валидированного пользовательского токена вашей собственной плоскости — никогда из клиентского ввода. Членство здесь намеренно не перепроверяется: поставить достоверную пару — половина контракта на стороне вызывающего. org_id опционален; без него уровень организации просто пропускается. purpose называет назначение, под которое резолвится ключ, — translation, glossary или tag_fix; любое другое значение — 400. correlation_id — ваш, едет в audit-ленту и возвращается в X-Correlation-ID.

Проход

В рамках политики credential_resolution провайдера (Vendors and Providers) сервис проходит фиксированную цепочку и возвращает первый активный default, который найдёт:

  1. USER — собственный default пользователя для провайдера.
  2. ORGANIZATION — когда org_id присутствует и провайдер допускает уровень: default организации. (В audit — с причиной USER_NOT_CONFIGURED_ORG_SELECTED.)
  3. PLATFORM — когда и политика, и ваш allow_platform_fallback это разрешают: общий платформенный default.

Ничего не найдено → 404 CREDENTIAL_NOT_CONFIGURED (провайдер существует; ключ никто не настроил — отличается от 404 PROVIDER_NOT_FOUND). Отключённый/удалённый провайдер → 409 PROVIDER_DISABLED. Каждое попадание и каждый промах записываются в audit-ленту.

Ответ

{
  "credential_id": "…",
  "provider_code": "deepl_api",
  "credential_source": "organization",
  "owner_type": "organization",
  "owner_id": "0d1e2f3a-…",
  "credentials": {"api_key": "the-actual-plaintext-key"},
  "configuration": {},
  "catalog_version": "2026.08.24",
  "resolved_at": "2026-08-12T12:30:00Z"
}

credential_source говорит, чей ключ вы держите — покажите это пользователю («работает на ключе вашей организации»). Обращайтесь с credentials как с радиоактивным материалом: используйте немедленно, никогда не сохраняйте, никогда не логируйте; ответ приходит с Cache-Control: no-store.

Никакого fallback при runtime-ошибках — так задумано

Если отрезолвленный ключ окажется сломанным у вендора (401, исчерпанная квота), сервис не выдаст вам следующий уровень при повторе: резолюция зависит только от сохранённого состояния, так что вы получите тот же ключ снова. Доносите сбой до владельца ключа; не сжигайте молча чужую квоту. allow_platform_fallback: false существует для обратной дисциплины — контрактов, требующих исключительно клиентских ключей.

Разобранный сквозной проход (попадание в user → fallback на org → fallback на платформу → промах): сценарий cookbook 06. Что UI должен показать перед отправкой задачи: Credential Status.