Skip to content

Глава 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 начинается с трёх компонентов, которые мы разберём в этой главе:

  1. Поставщик идентичности (IdP) — единая точка аутентификации
  2. Протоколы — SAML, OIDC, OAuth 2.0 — язык, на котором говорят IdP и приложения
  3. MFA — от TOTP до FIDO2/Passkeys, с акцентом на фишинго-устойчивость

Архитектура поставщика идентичности (IdP)

Поставщик идентичности (IdP) — центральный компонент в архитектуре Zero Trust. В терминологии NIST SP 800-207 (Section 2) IdP является одним из «источников данных» для Механизма политик (PE): PE запрашивает у IdP подтверждение идентичности субъекта перед принятием решения о доступе.

Три модели развёртывания IdP

МодельПримерыКонтроль данныхСтоимостьПодходит для
SaaSOkta, Microsoft Entra ID, Google WorkspaceДанные у вендораPer-user/monthОрганизации любого размера, приоритет — скорость внедрения
Self-hostedKeycloak, 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 matchingRedirect 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 три ключевых элемента:

  1. ID Token — JWT с утверждениями об идентичности (claims: sub, iss, aud, exp, iat, nonce, email, name)
  2. UserInfo Endpoint — API для получения дополнительных атрибутов пользователя
  3. Discovery — стандартизированный endpoint {issuer}/.well-known/openid-configuration для автоматического обнаружения конфигурации

ID Token vs Access Token:

СвойствоID TokenAccess Token
НазначениеИдентичность — кто пользовательАвторизация — что приложение может делать
АудиторияКлиентское приложение (Relying Party)API / Resource Server
ФорматОбязательно JWT (по спецификации OIDC)Любой формат (часто JWT, но не обязательно)
Ключевые claimssub, iss, aud, exp, name, emailscope, 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Существующая экосистема, зрелые интеграции
Новые веб/мобильные приложения, SPAOIDCJSON/JWT, поддержка мобильных, Discovery
API-to-API, M2M авторизацияOAuth 2.0 Client CredentialsДелегированный доступ без идентичности пользователя
Микросервисы + идентичность пользователяOIDC + OAuth 2.0ID 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 (домену):

  1. При регистрации браузер передаёт аутентификатору origin (например, https://login.example.com)
  2. Аутентификатор создаёт ключевую пару, привязанную к этому origin
  3. При входе аутентификатор проверяет 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 состоит из двух спецификаций:

СпецификацияОрганизацияТекущая версияДата
WebAuthnW3CLevel 3 (Candidate Recommendation Snapshot)13 января 2026
CTAPFIDO Alliance2.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-уведомления.»

Одобренные фишинго-устойчивые методы:

  1. PIV / Derived PIV — смарт-карты федерального правительства
  2. 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:

МетрикаЗначениеКонтекстИсточник
Учётных записей с поддержкой passkeys15+ млрдГлобально, декабрь 2024FIDO Alliance Announcement
Организаций, внедряющих passkeys87%Опрос 400 руководителей (US/UK, 500+ сотрудников), сентябрь 2024FIDO Enterprise Report 2025
Успешность входа с passkey93% vs 63%Выборка компаний, внедривших passkeysFIDO Passkey Index 2025

Аппаратные ключи: YubiKey vs Google Titan

ХарактеристикаYubiKey 5 NFCGoogle Titan (USB-C/NFC)
ПротоколыFIDO2, U2F, PIV, OATH, OpenPGPFIDO2, 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
InitialMFA с несколькими факторами; начальная валидация атрибутовTOTP + conditional access по локации
AdvancedФишинго-устойчивая MFA; начальный passwordlessFIDO2 security keys; Entra CA с risk-based policies
OptimalНепрерывная валидация с фишинго-устойчивой MFAPasskeys + 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:

yaml
# 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

bash
docker compose up -d

Дождитесь запуска (обычно 15-30 секунд). Проверьте готовность:

bash
curl -s http://localhost:8080/health/ready | python3 -m json.tool

Шаг 2: Создание realm и OIDC-клиента через CLI

Все операции выполняем через kcadm.sh из контейнера Keycloak:

bash
# Войти в 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

Установите пароль:

bash
# Получить 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

bash
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.

bash
# Получить токены (только для тестирования!)
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)

bash
# Включить 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:

  1. Откройте в браузере: http://localhost:8080/realms/zero-trust-lab/account
  2. Войдите как alice / SecurePass1!
  3. Keycloak покажет QR-код для TOTP
  4. Отсканируйте в FreeOTP или Google Authenticator
  5. Введите 6-значный код для подтверждения

Шаг 6: Проверка — вход теперь требует MFA

Повторите запрос токена из Шага 4. Запрос завершится ошибкой, потому что Direct Access Grant не поддерживает интерактивный TOTP-ввод. Это подтверждает, что MFA активна:

bash
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: Очистка

bash
docker compose down -v

Что дальше

Эта лабораторная работа поднимает вас с уровня Traditional (пароль без MFA) на Initial (MFA с TOTP). Следующие шаги к Advanced и Optimal:

ШагУровень CISAЧто настроить
Добавить WebAuthn как 2FAAdvancedrequired-actions/webauthn-register в Keycloak
Включить Passkeys (passwordless)Advanced → OptimalKeycloak 26.4+, WebAuthn Passwordless Policy
Conditional flows по ролиAdvancedConditional subflow + Condition - User Role
Интеграция с device complianceOptimalKeycloak + external IdP с device trust signals

Ключевые выводы

  1. IdP — единая точка правды об идентичности. Без централизованного IdP невозможно реализовать ни один из принципов Zero Trust.

  2. OIDC — протокол для нового стека, SAML — для legacy. Используйте OIDC с Authorization Code Flow + PKCE для всех новых приложений.

  3. Фишинго-устойчивая MFA — не опция, а требование. OMB M-22-09 прямо запрещает SMS, TOTP, push для федеральных агентств. NIST SP 800-63B-4 требует предлагать фишинго-устойчивый вариант на уровне AAL2 и выше.

  4. Passkeys — ближайшее будущее. 87% enterprise-организаций (US/UK) внедряют passkeys; 15+ млрд аккаунтов поддерживают их. Synced passkeys = AAL2; device-bound passkeys с неэкспортируемым ключом могут соответствовать AAL3.

  5. Conditional Access превращает бинарное решение (allow/deny) в контекстное. Комбинация identity + device + location + risk = основа для непрерывной верификации.

В Главе 6 мы рассмотрим следующий уровень: управление привилегированным доступом (PAM), Just-in-Time (JIT) привилегии и HashiCorp Vault.

Опубликовано под лицензией CC BY-SA 4.0