Токены и сроки
Форматы и сроки жизни code, access, refresh и ID token, ротация refresh и причины досрочного отзыва.
Все токены провайдера, кроме ID token, непрозрачны: это случайные 32 байта в base64url с префиксом типа. В Calab хранятся только их SHA-256-хэши, поэтому восстановить или показать токен повторно нельзя.
Сводка
| Что | Формат | Срок жизни | Примечание |
|---|---|---|---|
client_id | calab_client_ + 43 символа | Пока клиент не удалён | Публичный идентификатор, не секрет |
| Секрет клиента | calab_os_ + 43 символа | Бессрочно; при смене прежний действует ещё 10 минут | Показывается один раз |
| Запрос на вход | — | 10 минут | Экран согласия должен уложиться в это время |
| Authorization code | calab_oc_ + 43 символа | 60 секунд, одноразовый | Привязан к клиенту, redirect_uri и PKCE |
| Access token | calab_oa_ + 43 символа | до 5 минут (expires_in) | Только для /userinfo |
| Refresh token | calab_or_ + 43 символа | 8 часов максимум, 30 минут без использования | Ротируется при каждом обмене |
| ID token | JWT, RS256 | Как у access token | Проверяется по jwks_uri |
Access token
Access token — пропуск только к /userinfo. Он не работает в REST API Calab, gateway и голосе, а токены приложения Calab и ботов, наоборот, не принимаются в /userinfo. Introspection нет: чтобы проверить токен, вызовите /userinfo — 401 invalid_token означает, что токен больше не действует.
Refresh token и ротация
Refresh token выдаётся, только если у клиента включено «Разрешить продолжение доступа» и пользователь на экране согласия оставил эту галочку.
- Каждый обмен (
grant_type=refresh_token) возвращает новый refresh token, новый access token и новый ID token (безnonce). Прежний refresh token сразу становится использованным. - Повторное предъявление уже использованного refresh token этим же клиентом считается утечкой: Calab отзывает всю цепочку (grant), и пользователю придётся войти заново. Льготного окна для повторов нет — если ответ потерялся по сети, нужен новый вход.
- Каждый обмен продлевает «бездействие» до 30 минут, но не дальше абсолютного предела в 8 часов от входа.
- Обмен можно использовать для сужения scopes (параметр
scope) — сужение сохраняется для всей цепочки. Расширить scopes обменом нельзя (invalid_scope).
ID token
JWT с заголовком alg: RS256 и kid. Claims: iss, sub, aud (= ваш client_id), iat, exp, auth_time, nonce (только при обмене кода), а также name при scope profile и email + email_verified: true при scope email и подтверждённом адресе. Неподтверждённый email не попадает ни в ID token, ни в /userinfo.
Ключи подписи настраивает оператор установки; новые ключи публикуются в jwks_uri заранее, а прежние остаются там на время перехода. Кэшируйте JWKS (сервер отдаёт Cache-Control: max-age=60) и при незнакомом kid перечитайте его один раз.
Subject (sub)
- Случайный идентификатор (32 байта в base64url), созданный для пары «пространство + участник».
- Постоянен: не меняется при смене имени, email, пересоздании клиента.
- Одинаков для всех клиентов одного пространства и разный в разных пространствах (у них и issuer разный).
- Не раскрывает внутренний UUID аккаунта.
Ключ учётной записи в вашем приложении — пара (iss, sub).
Когда доступ заканчивается раньше срока
Calab заново проверяет права при каждом обмене кода, refresh и вызове /userinfo. Доступ (вся цепочка grant) прекращается, если:
- пользователь отозвал доступ в «OAuth-приложения» или вышел из сессии Calab, из которой входил;
- участника удалили из пространства, забанили или каталог (AD) закрыл ему доступ;
- администратор изменил redirect URI, origins, scopes или refresh у клиента, сменил секрет или удалил клиент;
- изменилась политика SSO пространства или истекло корпоративное подтверждение;
- закончился тариф Business / Enterprise или пространство приостановлено;
- клиент повторно предъявил использованный code или refresh token.
На /token это выглядит как 400 invalid_grant, на /userinfo — 401 invalid_token. Правильная реакция одна — начать вход заново.