Токены сервисной плоскости
Client-credentials токены от кросс-сервисного auth-сервера и три scope, которые делят /internal.
Всё под /internal/v1/* аутентифицируется токеном OAuth 2.0 client-credentials от кросс-сервисного auth-сервера (cross-auth): ваш сервис аутентифицируется своим приватным ключом (private_key_jwt), называет этот сервис ресурсом и получает короткоживущий RS256 JWT, чей scope решает, что ему здесь можно. Пользовательские токены на этой плоскости не работают никогда.
Получение токена
import httpx
token = httpx.post(CROSS_AUTH_TOKEN_URL, data={
"grant_type": "client_credentials",
"client_id": "translation-service",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": signed_client_jwt, # signed with your registered key
"resource": "https://provider-credentials.internal",
}).json()["access_token"]
resource — это логический идентификатор данного сервиса в auth-реестре (не сетевой URL); сами запросы затем идут на публичный домен сервиса как обычно. Какие клиенты могут держать какие scope — матрица доступа auth-реестра: онбординг нового потребителя — это изменение реестра там, а не изменение здесь.
Три scope
| Scope | Открывает | Типичный держатель |
|---|---|---|
provider-credentials.invoke |
resolve | рантаймы перевода |
provider-credentials.admin |
администрирование credentials | бэкенд админ-панели |
provider-credentials.reveal |
раскрытие plaintext | бэкенд админ-панели, выдаётся отдельно |
Ни один не подразумевает другой — разделение двунаправленно нарочно: админский токен не может читать plaintext (ни через resolve, ни через reveal), а invoke-токен не может администрировать. Валидный токен с неверным scope — 403; отсутствующий/невалидный токен — 401.
Конвенции этой плоскости
X-Admin-Actor— админ- и reveal-вызовы атрибутируют человека-оператора за сервисом (Internal Admin API); на reveal обязателен.correlation_id— resolve принимает его в теле и протягивает через audit-ленту.- Fail-closed — развёртывание без конфигурации сервисной аутентификации отвечает
401на всю плоскость, вместо того чтобы кому-то доверять.
Сама регистрация (клиентский ключ, resource URI, выдача scope) живёт в репозитории и документации auth-сервера; с точки зрения этого сервиса потребитель либо приходит с нужным scope, либо нет.