Перейти до вмісту

Єдиний вхід

Єдиний вхід дає зовнішньому провайдеру ідентичності (IdP) вирішувати, кому дозволено входити на ваш сервер Control Center. Підтримуються два протоколи — SAML 2.0 та OpenID Connect — і обидва приводять в одне місце: щойно випущені облікові дані пристрою, які далі ніде не відрізнити від запрошення чи QR-прив’язування.

Входи SAML опосередковує браузер. IdP ніколи не відкриває з’єднання з вашим сервером; усе переносить браузер користувача:

browser ──> /saml/login ──> IdP ──POST SAMLResponse──> /saml/acs
│ verify
▼
provision user (maybe)
│
▼
browser handoff: device PSK in the URL
fragment (never a query parameter)

Оскільки кур’єром є браузер, сервер за NAT цілком працює для входів: localhost, LAN, Tailscale, VPN або тунель — усе годиться; лише браузер користувача має дістатися ACS URL. Ретранслятор WebSocket, який використовує віддалене керування з телефона, не здатен перенести повний HTTP-обмін, саме тому точки входу SSO завжди націлені на HTTP-джерело сервера.

OpenID Connect має ту саму форму з обміном кодом авторизації + PKCE; твердження читаються з кінцевої точки токенів емітента через TLS, тож браузер узагалі не надає даних ідентичності.

Control Center навмисно розділяє відповідальність:

Компонент Де Відповідає за
нативний cc_saml packages/cc_natives/native/saml/ перевірка XML-DSig, канонікалізація, перевірка профілю SAML — делеговано закріпленому чисто-Rust крейту saml за безстановим C ABI
SamlService / OidcService cc_server_core стан входу (трекери запитів у стані очікування, дедуплікація повторів), перемикачі політики перевірки, спільний виклик підготовки
SsoProvisioner cc_server_core знайти або створити користувача, закріпити суб’єкта провайдера, надати членства за політикою автоматичного членства
ScimService cc_server_core поверхня push для SCIM 2.0 (життєвий цикл підготовки й скасування підготовки)
SsoSettingsService cc_server_core збережені рядки з’єднань, повторне застосування на льоту, токен SCIM

Тут навмисно немає чисто-Dart криптографічного запасного варіанта для SAML: саморобні XML-DSig/канонікалізація — саме те місце, де живуть уразливості обгортання підпису, тож відсутня бібліотека cc_saml відхиляє і вхід SAML, і запуск сервера. Нативний компонент за задумом безстановий — стан між запитами живе в сервісах Dart, одноразовий і недовговічний.

Усередині перевіреного нативного компонента та сервісу, у такому порядку:

  1. підпис твердження (потрібен завжди; підпис конверта відповіді — необов’язковий залежно від конфігурації) — структурно стійкий до обгортання підпису, бо перевірене навантаження прив’язане до перевіреного елемента,
  2. емітент збігається з налаштованим IdP,
  3. аудиторія називає цього постачальника послуг,
  4. призначення — це наш ACS URL,
  5. InResponseTo збігається з виданим нами AuthnRequest, що очікує (незапрошені відповіді, ініційовані IdP, типово вимкнені),
  6. вікна часу життя вкладаються в розбіжність годинників (типово 90s) і
  7. ідентифікатор твердження раніше не траплявся (кеш повторів).

Невдачі повертаються типізованими кодами — signature, expired, audience, destination, issuer, request-match — а кінцеві точки відповідають загальними помилками, тож нападник не дізнається нічого про те, чому підробка не вдалася.

Облікові записи та закріплення суб’єкта

Розділ із назвою «Облікові записи та закріплення суб’єкта»

Перший вхід через SSO закріплює за обліковим записом незмінний суб’єкт провайдера (issuer разом із SAML NameID / OIDC sub або SCIM externalId). Відтоді вхід ідентифікує суб’єкт, а не адреса електронної пошти. Якщо хтось інший згодом представить ту саму адресу від того самого чи іншого IdP, закріплений обліковий запис йому відмовить. Саме це не дає перевикористаній адресі в провайдера стати захопленням облікового запису.

JIT-підготовка відбувається під час входу (SsoProvisioner). SCIM — це окрема поверхня push (ScimService), яка закріплює той самий суб’єкт у рядку користувача; членства в робочих просторах вона не надає. Скасування підготовки — SCIM active: false або DELETE — відмовляє, якщо обліковий запис є власником робочого простору (спершу передайте володіння). Інакше воно спершу відкликає всі облікові дані пристроїв (сеанси спадають за секунди завдяки спостереженню за пристроями), прибирає всі членства в робочих просторах і позначає обліковий запис деактивованим. Рядок користувача залишається: атрибуція незмінна. Повторна активація відновлює вхід, але ніколи не повертає членства.

  • Зіставлення груп із ролями відбувається під час входу з атрибутів SAML / тверджень OIDC — надіслані групи SCIM не зберігаються.
  • Роль власника недосяжна через SSO — ні як типова роль, ні через зіставлення груп.
  • Ретранслятор WebSocket ніколи не буває каналом SSO; телефони, які дістаються сервера лише через ретранслятор, не можуть завершити проти нього обмін через браузер.