Метод аутентификации SAML
Метод saml позволяет аутентифицировать пользователей в Deckhouse Stronghold через внешний SAML 2.0 Identity Provider по профилю Web SSO.
Этот метод подходит для входа в Stronghold UI через браузер, а также для собственных интеграций, которые запускают SAML-сценарий через HTTP API. Stronghold выступает в роли SAML Service Provider, валидирует ответ от Identity Provider и затем выдает токен Stronghold в соответствии с выбранной ролью.
Как это работает
Сценарий входа состоит из трех этапов:
- Клиент вызывает
auth/<mount>/sso_service_urlи получает URL для перехода к Identity Provider и временныйtoken_poll_id. - Пользователь проходит аутентификацию у Identity Provider, после чего тот отправляет подписанный SAML-ответ в
auth/<mount>/callback. - Клиент обменивает
token_poll_idиclient_verifierна токен черезauth/<mount>/token.
Stronghold поддерживает два режима клиента:
browserдля UI-сценариев;cliдля внешних инструментов, которые открывают страницу IdP в браузере и затем опрашивают endpoint выдачи токена.
Включение метода
d8 stronghold auth enable samlПо умолчанию метод будет смонтирован по пути auth/saml. При необходимости можно использовать другой путь:
d8 stronghold auth enable -path=corp-saml samlКонфигурация
Перед началом работы Stronghold нужно настроить как SAML Service Provider.
Основные параметры:
entity_id- идентификатор Service Provider, который должен совпадать с настройками приложения на стороне Identity Provider.acs_urls- список разрешенных callback URL для Assertion Consumer Service.default_role- необязательная роль по умолчанию. Если она задана, при старте логина роль можно не передавать явно.idp_metadata_url- URL метаданных Identity Provider.idp_sso_url,idp_entity_idиidp_cert- ручная альтернативаidp_metadata_url.validate_response_signatureиvalidate_assertion_signature- параметры проверки подписей. Для production рекомендуется включать оба, если IdP умеет подписывать и response, и assertion.verbose_logging- расширенное логирование SAML-обмена. Используйте только для диагностики.
Настройка через метаданные IdP
d8 stronghold write auth/saml/config \
entity_id="https://stronghold.example.com/v1/auth/saml" \
acs_urls="https://stronghold.example.com/v1/auth/saml/callback" \
idp_metadata_url="https://idp.example.com/app/stronghold/sso/saml/metadata" \
default_role="employees" \
validate_response_signature=true \
validate_assertion_signature=trueРучная настройка
Если метаданные IdP недоступны, можно задать параметры вручную:
d8 stronghold write auth/saml/config \
entity_id="https://stronghold.example.com/v1/auth/saml" \
acs_urls="https://stronghold.example.com/v1/auth/saml/callback" \
idp_sso_url="https://idp.example.com/sso" \
idp_entity_id="https://idp.example.com/entity" \
idp_cert=@idp-signing-cert.pem \
validate_response_signature=true \
validate_assertion_signature=trueЕсли в acs_urls задано несколько адресов, при запуске сценария входа клиент должен явно передать нужный acs_url.
Assertion Consumer Service URLs
Параметр acs_urls определяет, на какие адреса Identity Provider может вернуть SAML-ответ после успешной аутентификации пользователя.
При настройке acs_urls убедитесь, что каждый адрес:
- совпадает с одним из callback URL, разрешенных в SAML-приложении на стороне Identity Provider;
- указывает на callback endpoint Stronghold вида
.../v1/auth/<mount>/callbackдля выбранного пути монтирования; - использует
https://в production.
Если Stronghold доступен по нескольким публичным адресам, можно указать несколько ACS URL:
d8 stronghold write auth/saml/config \
entity_id="https://stronghold.example.com/v1/auth/saml" \
acs_urls="https://primary.example.com/v1/auth/saml/callback,https://secondary.example.com/v1/auth/saml/callback" \
idp_metadata_url="https://idp.example.com/app/stronghold/sso/saml/metadata"Если вы используете namespaces, учитывайте путь пространства имён в API URL либо передавайте заголовок X-Vault-Namespace, чтобы callback URL соответствовал реальному расположению auth mount.
Роли
Роли SAML определяют, какие субъекты и атрибуты из SAML-утверждения допускаются к аутентификации, а также какие параметры токена будут применены после входа.
Основные параметры роли:
bound_subjects- ограничивает допустимые SAML subject.bound_subjects_type- тип сопоставления:stringилиglob.bound_attributes- список обязательных атрибутов assertion и ожидаемых значений.bound_attributes_type- тип сопоставления значений атрибутов:stringилиglob.groups_attribute- атрибут, из которого Stronghold создаст Identity group aliases.alias_metadata- статические метаданные, которые будут записаны в entity alias.- параметры токена, такие как
token_policies,token_ttl,token_max_ttl,token_periodиtoken_bound_cidrs, работают так же, как и в других auth methods.
Пример роли:
d8 stronghold write auth/saml/role/employees \
bound_subjects="*@example.com" \
bound_subjects_type="glob" \
bound_attributes=department=platform \
groups_attribute="memberOf" \
token_policies="default,developers" \
token_ttl="1h"Если IdP возвращает multivalue-атрибуты, bound_attributes может совпасть с любым из ожидаемых значений. Имена атрибутов сопоставляются без учета регистра.
Ограничения по атрибутам
После того как Identity Provider аутентифицировал пользователя, Stronghold проверяет ограничения роли по содержимому SAML-утверждения:
bound_subjectsсопоставляется с SAML subject;bound_attributesсопоставляется с обязательными атрибутами assertion и допустимыми значениями.
Это позволяет выдавать доступ только выбранным пользователям или группам из Identity Provider. Например:
d8 stronghold write auth/saml/role/support \
bound_subjects="*@example.com" \
bound_subjects_type="glob" \
bound_attributes=groups="support,engineering" \
token_policies="support-ro"Такая роль разрешит вход только пользователям с subject, оканчивающимся на @example.com, и с атрибутом groups, содержащим support или engineering.
Для платформ Microsoft group membership часто приходит в атрибуте http://schemas.microsoft.com/ws/2008/06/identity/claims/groups. В этом случае используйте именно это имя атрибута в bound_attributes и, при необходимости, в groups_attribute.
Привязка SAML-групп к Stronghold Identity
Если вы хотите, чтобы членство в SAML-группах выдавало политики Stronghold через Identity, задайте groups_attribute в роли и создайте соответствующие внешние Identity groups и aliases.
Общий сценарий:
- Создайте внешнюю Identity group с нужными политиками.
- Получите
mount accessorдля SAML auth method. - Создайте
group alias, имя которого совпадает со значением, приходящим в SAML-атрибуте.
Пример команд:
d8 stronghold write identity/group \
name="SamlDevelopers" \
type="external" \
policies="developers"d8 stronghold auth list -format=jsond8 stronghold write identity/group-alias \
name="engineering" \
mount_accessor="<saml-mount-accessor>" \
canonical_id="<identity-group-id>"При такой настройке SAML-логин, который возвращает значение engineering в атрибуте, указанном в groups_attribute, будет связан с внешней Identity group.
Вход через UI
Stronghold UI поддерживает вход через SAML напрямую.
Типичный сценарий:
- Выберите метод входа
SAMLна форме логина. - Укажите имя роли, если для mount path не задан
default_role. - Нажмите
Sign In. - Пройдите аутентификацию у внешнего Identity Provider.
- После успешного callback Stronghold выдаст токен и выполнит вход.
Запуск логина через API
Этот API-сценарий полезен для собственных порталов, оберток и внешних CLI-инструментов.
1. Сгенерируйте verifier и challenge
Параметр client_challenge должен быть base64-кодированным SHA-256 хешем от client_verifier.
verifier="$(uuidgen)"
challenge="$(printf '%s' "$verifier" | openssl dgst -sha256 -binary | base64)"2. Запросите SSO URL
curl \
--request POST \
--data "{\"role\":\"employees\",\"client_challenge\":\"$challenge\",\"client_type\":\"browser\"}" \
https://stronghold.example.com/v1/auth/saml/sso_service_urlВ ответе Stronghold вернет:
sso_service_url- URL для перенаправления пользователя к Identity Provider;token_poll_id- идентификатор для финального обмена на токен.
Если настроено несколько ACS URL, добавьте в запрос параметр acs_url.
3. Обменяйте временное состояние на токен
После того как IdP вернет пользователя обратно и Stronghold примет SAML-ответ, обменяйте poll id на токен:
curl \
--request POST \
--data "{\"token_poll_id\":\"<poll-id>\",\"client_verifier\":\"$verifier\"}" \
https://stronghold.example.com/v1/auth/saml/tokenТокен возвращается в auth.client_token.
Практические замечания
- В production используйте только
https://ACS URL. - Если IdP умеет подписывать и response, и assertion, включайте обе проверки подписи.
- Не оставляйте
verbose_logging=trueв production, так как в логах могут оказаться чувствительные SAML-данные. - Если у роли задан
token_bound_cidrs, финальный запрос наtokenдолжен приходить с разрешенного клиентского адреса. - В SAML-роли должно быть задано хотя бы одно условие допуска:
bound_subjectsилиbound_attributes. - Если настроено несколько
acs_urls, клиент должен передавать корректныйacs_urlпри запуске сценария входа.