Токены пользовательской плоскости
Обменяйте логин-сессию на короткоживущий токен под этот сервис, и как маппятся роли.
Пользовательская плоскость принимает ровно один вид токена: короткоживущий exchange-токен, отчеканенный identity-провайдером (auth.console) с audience provider-credentials-service. Логин/менеджмент-токен — даже валидный — отклоняется: дисциплина audience — это один JWT, один целевой сервис.
Флоу
- Залогиньтесь у identity-провайдера:
POST /v1/auth/login. Аккаунты, состоящие в нескольких организациях, получаютstatus: org_selection_requiredи завершают черезPOST /v1/auth/select-org— выбранная организация становитсяorg_idтокена. - Обменяйте сессию на токен под сервис:
POST /v1/auth/token/exchangeс{"audience": "provider-credentials-service"}. Результат — access-only JWT (ES256, живёт минуты, без refresh), несущийsub(UUID пользователя),org_idи сырые организационныеroles. - Вызывайте этот сервис с
Authorization: Bearer <token>. Когда токен истечёт, обменяйте снова — ваш якорь обновления — логин-сессия, а не этот сервис.
import httpx
auth = httpx.post(f"{AUTH_BASE}/v1/auth/login", json={"email": EMAIL, "password": PASSWORD}).json()
# ... handle org selection / MFA states per the auth service's own docs ...
exchange = httpx.post(
f"{AUTH_BASE}/v1/auth/token/exchange",
headers={"Authorization": f"Bearer {auth['access_token']}"},
json={"audience": "provider-credentials-service"},
).json()
TOKEN = exchange["access_token"]
Identity-провайдер публикует собственную вики разработчика с полной стейт-машиной логина; эта страница покрывает только то, что нужно от него этому сервису.
Что должен нести токен
iss/aud— сконфигурированный издатель иprovider-credentials-service; всё прочее —401.sub— пользователь, канонический UUID (неканонические формы отклоняются).org_id— опционален; если присутствует — канонический UUID. Отсутствие означает «нет контекста организации»: Organization Credentials отвечает403, а Credential Status сообщаетnullдля уровня организации.roles— сырые организационные роли (owner,admin,member,viewer).
Как маппятся роли
Два независимых маппинга читают один и тот же клейм roles:
- Сервисные роли (
JWT_ROLE_MAP, по умолчаниюowner→user, admin→user, member→user): дают роль §5.1, которая гейтит эндпоинты.viewerне маппится ни во что — такие токены получают401. Повышенные роли (provider_admin,auditor) никогда не выводятся из орг-ролей по умолчанию; их выдача — осознанное решение развёртывания. - Менеджеры организации (
JWT_ORG_MANAGER_ROLES, по умолчаниюowner,admin): сверяются с сырыми ролями, чтобы гейтить Organization Credentials — намеренно переживая сплющивание выше.
Итак, дефолтное развёртывание читается так: каждый участник организации — user; управляют credentials организации только владельцы и админы.
Dev-режим аутентификации
Локальная разработка может вовсе пропустить identity-провайдера: DEV_AUTH_ENABLED=true принимает заголовки X-Dev-User-Id, X-Dev-Roles, X-Dev-Org-Id, X-Dev-Org-Roles, применяя те же правила UUID и ролей. Запросы с заголовком Authorization всегда валидируются как JWT, несмотря ни на что. В production-сборках отклоняется.