Глава 5. Фундамент идентичности
В Главе 1 мы видели, как украденный пароль VPN без MFA открыл DarkSide доступ к Colonial Pipeline. В Главе 2 — как CISA ZTMM ставит идентичность первым столпом из пяти. Эта глава отвечает на вопрос: как построить фундамент идентичности, на котором держится вся архитектура Zero Trust.
Зачем нужен единый фундамент идентичности
NIST SP 800-207 (Section 2, Tenet 1) формулирует: «Все источники данных и вычислительные сервисы считаются ресурсами». Тенет 2 уточняет: «Весь обмен данными защищается, независимо от расположения в сети». Но защита невозможна без ответа на базовый вопрос — кто запрашивает доступ?
Источник: NIST SP 800-207, Section 2
Три проблемы организаций, которые не имеют единого фундамента идентичности:
1. Разрозненные хранилища. Active Directory для десктопов, LDAP для legacy-приложений, локальные базы пользователей в SaaS-сервисах. Пользователь увольняется — его учётная запись продолжает жить в трёх из пяти систем.
2. Слабая аутентификация. Пароли без второго фактора. Даже если MFA внедрена — SMS-коды, которые перехватываются через SIM-swapping. В CISA ZTMM v2.0 уровень Traditional для идентичности определяется как «пароли или простая MFA» — именно то, от чего нужно уходить.
3. Статический доступ. Права назначаются при создании учётной записи и никогда не пересматриваются. Нет контекста: неважно, с какого устройства подключается администратор — из офиса или из кафе с публичным Wi-Fi.
Источник: CISA ZTMM v2.0, Identity Pillar
Уровень Optimal в CISA ZTMM требует: «непрерывная валидация с фишинго-устойчивой MFA на протяжении всей сессии». Путь к Optimal начинается с трёх компонентов, которые мы разберём в этой главе:
- Поставщик идентичности (IdP) — единая точка аутентификации
- Протоколы — SAML, OIDC, OAuth 2.0 — язык, на котором говорят IdP и приложения
- MFA — от TOTP до FIDO2/Passkeys, с акцентом на фишинго-устойчивость
Архитектура поставщика идентичности (IdP)
Поставщик идентичности (IdP) — центральный компонент в архитектуре Zero Trust. В терминологии NIST SP 800-207 (Section 2) IdP является одним из «источников данных» для Механизма политик (PE): PE запрашивает у IdP подтверждение идентичности субъекта перед принятием решения о доступе.
Три модели развёртывания IdP
| Модель | Примеры | Контроль данных | Стоимость | Подходит для |
|---|---|---|---|---|
| SaaS | Okta, Microsoft Entra ID, Google Workspace | Данные у вендора | Per-user/month | Организации любого размера, приоритет — скорость внедрения |
| Self-hosted | Keycloak, Authentik | Полный контроль | Инфраструктура + ops | Регулируемые отрасли, air-gapped среды, требования data residency |
| Гибрид | Entra ID + Keycloak federation | Распределённый | Комбинированная | Крупные организации с legacy и cloud |
Okta
Okta — SaaS-платформа управления идентичностями, одна из наиболее распространённых в enterprise-сегменте. Ключевые возможности для Zero Trust:
- Universal Directory — единый каталог с федерацией из AD, LDAP, HR-систем
- Adaptive MFA — MFA с учётом контекста (устройство, локация, поведение)
- Identity Threat Protection with Okta AI — непрерывная оценка рисков на основе Shared Signals Framework (SSF) и CAEP (см. раздел Conditional Access ниже)
- Device Trust — интеграция с Jamf, Intune, CrowdStrike для оценки состояния устройств
Источник: Okta Identity Threat Protection
Microsoft Entra ID
Microsoft Entra ID (бывший Azure AD, переименован в 2023) — IdP от Microsoft, глубоко интегрированный с экосистемой Microsoft 365 и Azure.
- Conditional Access — механизм политик, учитывающий identity + device + location + risk level
- Entra ID Protection — ML-детекция рисков (atypical travel, password spray, malware-linked IP и др.)
- Passwordless — поддержка FIDO2 security keys, Microsoft Authenticator, Windows Hello
- Continuous Access Evaluation (CAE) — отзыв токенов в реальном времени при изменении условий
Источник: Microsoft Entra Conditional Access; Entra ID Protection Risk Detections
Keycloak (self-hosted)
Keycloak — open-source IdP от Red Hat (ранее WildFly, с версии 17+ на Quarkus). Текущая стабильная версия: 26.5.2 (январь 2026).
- Поддержка протоколов: OIDC, SAML 2.0, OAuth 2.0
- MFA: TOTP (с версии 1.0), WebAuthn/FIDO2 (с версии 8.0, 2019), Passkeys GA (с версии 26.4, сентябрь 2025)
- Федерация: Identity Brokering (OIDC, SAML, Social Login), Federated Client Authentication для SPIFFE JWT SVID и Kubernetes service account tokens (preview, 26.4/26.5)
- Conditional Flows: настраиваемые потоки аутентификации с условиями (по роли, устройству, клиенту)
Federated Client Authentication — важная новая возможность: клиенты могут аутентифицироваться без секретов, используя JWT SVID (SPIFFE) или Kubernetes service account tokens. Это напрямую связано с идентичностью рабочих нагрузок, которую мы детально разберём в Главе 7.
Источники: Keycloak 26.5.2 Release; Passkeys in 26.4; Federated Client Authentication
Протоколы аутентификации: SAML, OIDC, OAuth 2.0
IdP и приложения общаются на одном из трёх основных протоколов. Выбор протокола определяет архитектуру интеграции, безопасность и удобство для пользователей.
SAML 2.0
Security Assertion Markup Language 2.0 — стандарт OASIS, утверждённый в марте 2005 года. До сих пор используется в enterprise SSO, хотя всё чаще уступает OIDC.
Как работает: IdP выдаёт XML-утверждения (assertions), подписанные цифровой подписью. Браузер перенаправляет assertion на Service Provider (SP) через HTTP POST или HTTP Redirect.
Сильные стороны:
- Зрелая экосистема: ADFS, PingFederate, Shibboleth
- Детальные атрибуты в assertion (должность, подразделение, роли)
- Широкая поддержка в корпоративных SaaS
Ограничения:
- XML-основанный — громоздкие сообщения, сложный парсинг
- Уязвимости класса XML Signature Wrapping (XSW) — атакующий вставляет вредоносный assertion, а SP обрабатывает подмену вместо легитимного (OWASP SAML Security Cheat Sheet)
- Не приспособлен для мобильных приложений, SPA и API-to-API
- Нет встроенной модели stateless-токенов (в отличие от JWT в OIDC)
Источники: OASIS SAML v2.0 Standard; RFC 7522 — SAML Profile for OAuth 2.0
OAuth 2.0 / 2.1
OAuth 2.0 (RFC 6749, октябрь 2012) — фреймворк авторизации. Отвечает на вопрос: «Что это приложение имеет право делать?». OAuth не отвечает на вопрос «Кто этот пользователь?» — для этого нужен OIDC.
OAuth 2.1 (draft-ietf-oauth-v2-1-14, на момент написания — Internet-Draft, ещё не финальный RFC) консолидирует best practices из нескольких RFC:
| Изменение в OAuth 2.1 | Описание |
|---|---|
| PKCE обязателен | Proof Key for Code Exchange (RFC 7636) обязателен для ВСЕХ клиентов, не только публичных |
| Implicit grant удалён | response_type=token больше не поддерживается |
| ROPC grant удалён | Resource Owner Password Credentials — удалён из спецификации |
| Exact redirect URI matching | Redirect URI сравниваются точным совпадением строк (без wildcards) |
| Bearer tokens в query string запрещены | Токены нельзя передавать через URI query parameters |
| Refresh tokens | Должны быть sender-constrained или одноразовыми |
Параллельно в январе 2025 года опубликован RFC 9700 (OAuth 2.0 Security Best Current Practice) — обновлённая модель угроз и рекомендации, расширяющие RFC 6749 и 6819.
Источники: RFC 6749 — OAuth 2.0; OAuth 2.1 Draft; RFC 9700 — Security BCP
OpenID Connect (OIDC)
OpenID Connect Core 1.0 — слой аутентификации поверх OAuth 2.0. Отвечает на вопрос: «Кто этот пользователь?». Стандартизирован OpenID Foundation; в 2025 году принят как ITU-T Recommendation X.1285 и ISO/IEC 26131:2024.
OIDC добавляет к OAuth 2.0 три ключевых элемента:
- ID Token — JWT с утверждениями об идентичности (claims:
sub,iss,aud,exp,iat,nonce,email,name) - UserInfo Endpoint — API для получения дополнительных атрибутов пользователя
- Discovery — стандартизированный endpoint
{issuer}/.well-known/openid-configurationдля автоматического обнаружения конфигурации
ID Token vs Access Token:
| Свойство | ID Token | Access Token |
|---|---|---|
| Назначение | Идентичность — кто пользователь | Авторизация — что приложение может делать |
| Аудитория | Клиентское приложение (Relying Party) | API / Resource Server |
| Формат | Обязательно JWT (по спецификации OIDC) | Любой формат (часто JWT, но не обязательно) |
| Ключевые claims | sub, iss, aud, exp, name, email | scope, aud, iss, exp, permissions |
| Куда отправлять | НЕ отправлять на API | В заголовке Authorization: Bearer |
Рекомендуемый flow: Authorization Code + PKCE (RFC 7636) — для всех типов клиентов: веб-приложения, SPA, мобильные. Implicit flow считается устаревшим.
Источники: OpenID Connect Core 1.0; ITU-T X.1285 (May 2025); RFC 7636 — PKCE
Когда что использовать
| Сценарий | Протокол | Почему |
|---|---|---|
| Enterprise SSO, legacy-приложения (ADFS, SAP) | SAML 2.0 | Существующая экосистема, зрелые интеграции |
| Новые веб/мобильные приложения, SPA | OIDC | JSON/JWT, поддержка мобильных, Discovery |
| API-to-API, M2M авторизация | OAuth 2.0 Client Credentials | Делегированный доступ без идентичности пользователя |
| Микросервисы + идентичность пользователя | OIDC + OAuth 2.0 | ID Token для «кто», Access Token для «что разрешено» |
| Legacy SAML + новые приложения | OIDC + SAML (Federation) | IdP как мост: SAML для legacy, OIDC для нового |
Большинство организаций используют оба протокола: SAML для унаследованных корпоративных приложений и OIDC для нового cloud-native стека. IdP (Okta, Entra ID, Keycloak) выступает мостом между мирами.
MFA: от TOTP к фишинго-устойчивой аутентификации
Эволюция MFA
Многофакторная аутентификация (MFA) — минимальное требование для любого уровня выше Traditional в CISA ZTMM. Но не все факторы одинаково устойчивы к атакам.
| Метод | Факторы | Фишинго-устойчив? | Проблемы |
|---|---|---|---|
| Пароль + SMS OTP | Знание + Владение | Нет | SIM-swapping, перехват SS7, social engineering |
| Пароль + TOTP | Знание + Владение | Нет | Real-time phishing proxy (evilginx2) перехватывает код |
| Пароль + Push | Знание + Владение | Нет | Push fatigue / MFA bombing — пользователь случайно подтверждает |
| FIDO2 Security Key | Владение + Inherence/Знание (PIN) | Да | Стоимость ключа (~$30-55), логистика |
| Passkey (synced) | Владение + Inherence (биометрия) | Да | Зависимость от cloud sync provider |
| Passkey (device-bound) | Владение + Inherence (биометрия) | Да | Потеря устройства = потеря доступа |
Почему FIDO2/Passkeys устойчивы к фишингу
Ключевое отличие FIDO2 от всех предыдущих методов MFA — привязка к origin (домену):
- При регистрации браузер передаёт аутентификатору origin (например,
https://login.example.com) - Аутентификатор создаёт ключевую пару, привязанную к этому origin
- При входе аутентификатор проверяет origin запроса. Если пользователь попал на фишинговый сайт
https://login.examp1e.com— приватный ключ просто не подпишет challenge, потому что origin не совпадает
Это называется verifier impersonation resistance (NIST SP 800-63B-4). Даже если пользователь перешёл по фишинговой ссылке и нажал «подтвердить» — аутентикатор не выдаст валидную подпись для чужого домена.
Источник: NIST SP 800-63B-4, Section on Verifier Impersonation Resistance
Стандарты FIDO2
FIDO2 состоит из двух спецификаций:
| Спецификация | Организация | Текущая версия | Дата |
|---|---|---|---|
| WebAuthn | W3C | Level 3 (Candidate Recommendation Snapshot) | 13 января 2026 |
| CTAP | FIDO Alliance | 2.2 (Proposed Standard) | 14 июля 2025 |
WebAuthn — это API браузера для взаимодействия с аутентификаторами. CTAP (Client to Authenticator Protocol) — протокол между платформой и внешним аутентификатором (USB, NFC, BLE).
Источники: W3C WebAuthn Level 3; CTAP 2.2 Proposed Standard
Passkeys: синхронизируемые и аппаратные
Passkeys — обобщающий термин FIDO Alliance для учётных данных на основе FIDO2/WebAuthn.
Синхронизируемые passkeys (synced) хранятся в credential manager (iCloud Keychain, Google Password Manager, 1Password, Dashlane) и синхронизируются между устройствами пользователя. NIST SP 800-63B-4 (июль 2025) признаёт их на уровне AAL2.
Аппаратные passkeys (device-bound) хранятся на конкретном устройстве (YubiKey, Titan Key, TPM) и не могут быть экспортированы. Могут соответствовать AAL3 по NIST SP 800-63B-4, при условии что аутентификатор обеспечивает неэкспортируемый приватный ключ и фишинго-устойчивость (verifier impersonation resistance). Не каждый device-bound passkey автоматически соответствует AAL3 — важны конкретные характеристики аутентификатора.
Источник: NIST SP 800-63B-4; Passkey Central: Passkey Types
Требования OMB M-22-09
OMB Memorandum M-22-09 (26 января 2022, во исполнение EO 14028) устанавливает требования к федеральным агентствам:
«Агентства должны прекратить поддержку методов аутентификации, которые не устойчивы к фишингу, включая протоколы, использующие номера телефонов для SMS или голосовых вызовов, одноразовые коды или push-уведомления.»
Одобренные фишинго-устойчивые методы:
- PIV / Derived PIV — смарт-карты федерального правительства
- FIDO2 / WebAuthn — открытый стандарт (memo прямо допускает «phishing-resistant authenticators that do not yet support PIV, such as FIDO2 and Web Authentication-based solutions»)
Хотя M-22-09 адресован федеральным агентствам, он задаёт направление для всей индустрии: если SMS OTP небезопасен для правительства, он небезопасен и для вас.
Источник: OMB M-22-09 (PDF)
Adoption: состояние на 2025-2026
По данным FIDO Alliance:
| Метрика | Значение | Контекст | Источник |
|---|---|---|---|
| Учётных записей с поддержкой passkeys | 15+ млрд | Глобально, декабрь 2024 | FIDO Alliance Announcement |
| Организаций, внедряющих passkeys | 87% | Опрос 400 руководителей (US/UK, 500+ сотрудников), сентябрь 2024 | FIDO Enterprise Report 2025 |
| Успешность входа с passkey | 93% vs 63% | Выборка компаний, внедривших passkeys | FIDO Passkey Index 2025 |
Аппаратные ключи: YubiKey vs Google Titan
| Характеристика | YubiKey 5 NFC | Google Titan (USB-C/NFC) |
|---|---|---|
| Протоколы | FIDO2, U2F, PIV, OATH, OpenPGP | FIDO2, U2F |
| Хранение passkeys | ~25 resident credentials | До 250 passkeys |
| NFC | Да | Да |
| PIV (смарт-карта) | Да | Нет |
| Цена | ~$50 | ~$30 |
| Для кого | Организации с требованиями PIV + FIDO2 | Организации, которым нужен только FIDO2 |
Источники: Yubico Products; Google Titan Security Key
Рекомендация: выдавайте сотрудникам два ключа (основной + резервный). Храните резервный в безопасном месте.
Conditional Access: решения на основе контекста
Фишинго-устойчивая MFA — необходимый, но не достаточный шаг. Zero Trust требует решений на основе контекста: кто входит, откуда, с какого устройства, с каким уровнем риска.
Концепция Conditional Access
Conditional Access — это политика вида if (conditions) → then (controls):
IF:
- Пользователь: группа "Финансы"
- Приложение: SAP
- Устройство: не корпоративное
- Локация: вне офисной сети
- Уровень риска: medium
THEN:
- Требовать фишинго-устойчивую MFA
- Ограничить сессию 1 часом
- Запретить скачивание файловMicrosoft Entra ID: Conditional Access + ID Protection
Microsoft Entra ID реализует наиболее зрелую модель Conditional Access в индустрии. Политика состоит из трёх блоков:
Assignments (Кому):
- Пользователи и группы
- Облачные приложения
- Условия: локация, платформа устройства, уровень риска
Conditions (Когда):
- Sign-in risk: anonymous IP, atypical travel, password spray, malware-linked IP, unfamiliar sign-in properties, verified threat actor IP и другие (полный список на Microsoft Learn)
- User risk: leaked credentials, anomalous user activity, attacker-in-the-middle
- Device platform: iOS, Android, Windows, macOS, Linux
Controls (Что делать):
- Grant: требовать MFA, требовать compliant device, требовать Entra hybrid join
- Session: sign-in frequency, Continuous Access Evaluation (CAE), app-enforced restrictions
Источник: Entra ID Conditional Access; Risk Detection Types
Continuous Access Evaluation (CAE) — механизм отзыва токенов в near real-time для поддерживаемых ресурсов (Exchange Online, SharePoint Online, Teams, MS Graph). В классической модели access token живёт 1 час и не может быть отозван до истечения. CAE позволяет Resource Server проверять: не отозвана ли сессия, не изменилась ли локация, не уволен ли пользователь — и реагировать в течение минут (до 15 минут для критических событий, мгновенно для смены IP-локации), а не часов.
Источник: Continuous Access Evaluation
Shared Signals Framework (SSF) и CAEP
В межвендорной среде (Okta + CrowdStrike + Zscaler) нужен стандартный способ обмена сигналами безопасности. Shared Signals Framework (SSF) и Continuous Access Evaluation Protocol (CAEP) — спецификации OpenID Foundation для этого:
- SSF Transmitter отправляет события (user risk detected, session revoked)
- SSF Receiver получает события и применяет политики (отозвать сессию, потребовать step-up MFA)
- CAEP определяет 5 типов событий для непрерывной оценки: session revoked, token claims change, credential change, assurance level change, device compliance change
Okta реализует SSF через Identity Threat Protection: получает сигналы от Jamf, CrowdStrike, Omnissa и транслирует их в entity risk detections для применения политик.
Источники: Okta SSF; OpenID SSF Specification
Mapping на CISA ZTMM
| Уровень CISA ZTMM | Что требуется по идентичности | Реализация |
|---|---|---|
| Traditional | Пароли или простая MFA | Пароль + SMS OTP |
| Initial | MFA с несколькими факторами; начальная валидация атрибутов | TOTP + conditional access по локации |
| Advanced | Фишинго-устойчивая MFA; начальный passwordless | FIDO2 security keys; Entra CA с risk-based policies |
| Optimal | Непрерывная валидация с фишинго-устойчивой MFA | Passkeys + CAE + SSF + device compliance signals |
Lab: Keycloak с OIDC и MFA
В этой лабораторной работе мы развернём Keycloak, настроим OIDC-клиент и принудительную MFA через TOTP. Это базовый набор, который поднимает организацию с уровня Traditional на Initial в CISA ZTMM.
Предварительные требования
- Docker и Docker Compose
- curl или браузер для тестирования
- TOTP-приложение (FreeOTP, Google Authenticator)
Шаг 1: Развёртывание Keycloak с PostgreSQL
Создайте файл docker-compose.yml:
# code/ch05-identity/docker-compose.yml
version: '3.9'
services:
postgres:
image: postgres:16
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: changeme
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- kc-net
keycloak:
image: quay.io/keycloak/keycloak:26.5.2
command: start-dev
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: changeme
KC_HEALTH_ENABLED: "true"
ports:
- "8080:8080"
depends_on:
- postgres
networks:
- kc-net
volumes:
pgdata:
networks:
kc-net:Примечание:
KC_BOOTSTRAP_ADMIN_USERNAME/KC_BOOTSTRAP_ADMIN_PASSWORD— переменные окружения Keycloak 26+. Они заменяют устаревшиеKEYCLOAK_ADMIN/KEYCLOAK_ADMIN_PASSWORD.
Источник: Keycloak: Getting Started with Docker; Running Keycloak in a Container
docker compose up -dДождитесь запуска (обычно 15-30 секунд). Проверьте готовность:
curl -s http://localhost:8080/health/ready | python3 -m json.toolШаг 2: Создание realm и OIDC-клиента через CLI
Все операции выполняем через kcadm.sh из контейнера Keycloak:
# Войти в Admin CLI
docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
config credentials \
--server http://localhost:8080 \
--realm master \
--user admin \
--password admin
# Создать realm
docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
create realms \
-s realm=zero-trust-lab \
-s enabled=true
# Создать confidential OIDC-клиент
docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
create clients -r zero-trust-lab \
-s clientId=zt-app \
-s enabled=true \
-s clientAuthenticatorType=client-secret \
-s secret=zt-app-secret \
-s 'redirectUris=["http://localhost:3000/*"]' \
-s 'webOrigins=["http://localhost:3000"]' \
-s standardFlowEnabled=true \
-s directAccessGrantsEnabled=false
# Создать тестового пользователя
docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
create users -r zero-trust-lab \
-s username=alice \
-s enabled=true \
-s email=alice@example.com \
-s emailVerified=trueУстановите пароль:
# Получить ID пользователя
USER_ID=$(docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
get users -r zero-trust-lab \
-q username=alice \
--fields id --format csv --noquotes)
# Установить пароль
docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
set-password -r zero-trust-lab \
--userid "$USER_ID" \
--new-password 'SecurePass1!'Шаг 3: Проверка OIDC Discovery
curl -s http://localhost:8080/realms/zero-trust-lab/.well-known/openid-configuration \
| python3 -m json.tool | head -20Вы увидите JSON с endpoint'ами: authorization_endpoint, token_endpoint, userinfo_endpoint, jwks_uri и поддерживаемые grant_types, response_types, scopes.
Шаг 4: Получение токена (Authorization Code Flow)
Для тестирования используем Direct Access Grant (только в dev-среде). В продакшне всегда используйте Authorization Code Flow + PKCE.
# Получить токены (только для тестирования!)
TOKEN_RESPONSE=$(curl -s -X POST \
http://localhost:8080/realms/zero-trust-lab/protocol/openid-connect/token \
-d "grant_type=password" \
-d "client_id=zt-app" \
-d "client_secret=zt-app-secret" \
-d "username=alice" \
-d "password=SecurePass1!" \
-d "scope=openid")
# Извлечь Access Token
echo "$TOKEN_RESPONSE" | python3 -m json.tool
# Декодировать ID Token (base64)
ID_TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "
import sys, json
data = json.load(sys.stdin)
print(data.get('id_token', 'N/A'))
")
echo "$ID_TOKEN" | cut -d'.' -f2 | base64 -d 2>/dev/null | python3 -m json.toolШаг 5: Включение обязательной MFA (TOTP)
# Включить Configure OTP как default action для всех новых пользователей
docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
update authentication/required-actions/CONFIGURE_TOTP \
-r zero-trust-lab \
-s defaultAction=true
# Принудительно потребовать OTP для существующего пользователя alice
docker compose exec keycloak /opt/keycloak/bin/kcadm.sh \
update users/$USER_ID -r zero-trust-lab \
-s 'requiredActions=["CONFIGURE_TOTP"]'Теперь при следующем входе alice будет перенаправлена на страницу настройки TOTP:
- Откройте в браузере:
http://localhost:8080/realms/zero-trust-lab/account - Войдите как
alice/SecurePass1! - Keycloak покажет QR-код для TOTP
- Отсканируйте в FreeOTP или Google Authenticator
- Введите 6-значный код для подтверждения
Шаг 6: Проверка — вход теперь требует MFA
Повторите запрос токена из Шага 4. Запрос завершится ошибкой, потому что Direct Access Grant не поддерживает интерактивный TOTP-ввод. Это подтверждает, что MFA активна:
curl -s -X POST \
http://localhost:8080/realms/zero-trust-lab/protocol/openid-connect/token \
-d "grant_type=password" \
-d "client_id=zt-app" \
-d "client_secret=zt-app-secret" \
-d "username=alice" \
-d "password=SecurePass1!" \
-d "scope=openid" | python3 -m json.toolОжидаемый ответ: "error": "invalid_grant" — Keycloak требует TOTP, но Direct Access Grant не может его предоставить. В продакшне пользователь пройдёт через браузерный Authorization Code Flow, где Keycloak покажет форму ввода TOTP-кода.
Шаг 7: Очистка
docker compose down -vЧто дальше
Эта лабораторная работа поднимает вас с уровня Traditional (пароль без MFA) на Initial (MFA с TOTP). Следующие шаги к Advanced и Optimal:
| Шаг | Уровень CISA | Что настроить |
|---|---|---|
| Добавить WebAuthn как 2FA | Advanced | required-actions/webauthn-register в Keycloak |
| Включить Passkeys (passwordless) | Advanced → Optimal | Keycloak 26.4+, WebAuthn Passwordless Policy |
| Conditional flows по роли | Advanced | Conditional subflow + Condition - User Role |
| Интеграция с device compliance | Optimal | Keycloak + external IdP с device trust signals |
Ключевые выводы
IdP — единая точка правды об идентичности. Без централизованного IdP невозможно реализовать ни один из принципов Zero Trust.
OIDC — протокол для нового стека, SAML — для legacy. Используйте OIDC с Authorization Code Flow + PKCE для всех новых приложений.
Фишинго-устойчивая MFA — не опция, а требование. OMB M-22-09 прямо запрещает SMS, TOTP, push для федеральных агентств. NIST SP 800-63B-4 требует предлагать фишинго-устойчивый вариант на уровне AAL2 и выше.
Passkeys — ближайшее будущее. 87% enterprise-организаций (US/UK) внедряют passkeys; 15+ млрд аккаунтов поддерживают их. Synced passkeys = AAL2; device-bound passkeys с неэкспортируемым ключом могут соответствовать AAL3.
Conditional Access превращает бинарное решение (allow/deny) в контекстное. Комбинация identity + device + location + risk = основа для непрерывной верификации.
В Главе 6 мы рассмотрим следующий уровень: управление привилегированным доступом (PAM), Just-in-Time (JIT) привилегии и HashiCorp Vault.