Sari la conținut

GSSO — Техническая документация

Acest conținut nu este încă disponibil în limba selectată.

Код документаSPEC-GSSO-2026 / Отчёт 04
Версия0.1-draft (исходный текст EN, имеющий преимущественную силу)
Дата2026-10-05
СтатусЧерновик: описывает планируемую систему. Код пока не существует
Сопутствующие отчёты00 Техническое задание · 01 ADR · 02 Требования · 03 Потребители и контракт · 05 Дорожная карта
ВерсияДатаИзменения
0.1-draft2026-10-05Представления C4, компоненты, модель данных, потоки, базовая конфигурация realm, безопасность, развёртывание, runbook перехода под управление, сайзинг, наблюдаемость, тестирование

1. Системный контекст (C4, уровень 1)

Section titled “1. Системный контекст (C4, уровень 1)”
flowchart TB
admin([Администратор IAM / владелец платформы / согласующий / аудитор / helpdesk])
staff([Сотрудник])
citizen([Гражданин])
apps[SaaS и PaaS gStack<br/>interdictii, cancelaria, gdocs, gregistry, drumuri,<br/>CRM, gDocFlow, gTenders, glog, gnotify, gstorage, gflow]
mob[gsso_mob GovSign]
gsso[[GSSO<br/>платформа идентификации и SSO]]
mpass[MPass / eID]
ldap[AD / LDAP учреждений]
glog[GLog]
gnotify[GNotify]
smtp[SMTP relay]
admin -- консоль --> gsso
staff -- вход / SSO --> gsso
citizen -- вход --> gsso
mob -- OIDC PKCE --> gsso
apps -- OIDC, JWKS, api/v1/app, события Kafka --> gsso
gsso -- SAML broker --> mpass
gsso -- федерация LDAP --> ldap
gsso -- события аудита --> glog
gsso -- оповещения, уведомления об истечении --> gnotify
gsso -- приглашения, письма сброса --> smtp

2. Контейнеры (C4, уровень 2)

Section titled “2. Контейнеры (C4, уровень 2)”
flowchart LR
subgraph edge[Периметр]
nginx[nginx / ingress<br/>sso.gstack… · gsso.gstack…]
end
subgraph gssoSys[GSSO]
web[gsso-web<br/>Angular + GDS<br/>статика]
gw[gsso-gateway<br/>шлюз JHipster 9.1 · BFF]
srv[gsso<br/>микросервис JHipster 9.1]
db[(PostgreSQL<br/>gsso)]
kc[Keycloak 26.6.x<br/>+ gsso-kc-extensions<br/>+ тема gstack]
kdb[(PostgreSQL<br/>keycloak)]
boot[gsso-bootstrap<br/>задание keycloak-config-cli]
end
kafka[[Kafka]]
glog[GLog]
gn[GNotify]
nginx --> web
nginx --> gw
nginx --> kc
gw -- /api/v1/** --> srv
gw -. OIDC code flow, клиент gsso-console .-> kc
srv -- Admin REST, SA gsso-reconciler --> kc
srv --- db
kc --- kdb
boot -- базовые realm --> kc
kc -- gsso.kc-events.v1 --> kafka
kafka --> srv
srv -- gsso.access-revoked.v1, gsso.grant.v1 --> kafka
srv -- аудит --> glog
srv -- уведомления --> gn
КонтейнерТехнологияОтветственность
gsso-webAngular (версия согласно JHipster 9.1.0), @gstack/gds-angular, ngx-translate ro/ru/enUI консоли; без token (cookie BFF)
gsso-gatewayшлюз JHipster 9.1.0 (Spring Cloud Gateway), клиент OAuth2Вход и сессия (BFF), CSRF, маршрутизация /api/v1/**, ограничения частоты запросов для зоны app
gssoмикросервис JHipster 9.1.0, Spring Boot, Hibernate, Liquibase, Kafka, keycloak-admin-client 26.xКаталог, предоставления доступа, reconciler, потребитель событий, ретрансляция в GLog, отчёты, API admin и app
Keycloakquay.io/keycloak/keycloak:26.6.x (собственный образ с расширениями + темой, kc.sh build)Аутентификация, token, сессии, MFA, федерация, консоль учётной записи
gsso-bootstrapadorsys/keycloak-config-cli, соответствующий 26.xПрименяет базовые конфигурации realm при развёртывании (идемпотентно)
PostgreSQL ×2в том виде, в каком генерирует JHipster 9.1.0 (gsso); версия, поддерживаемая Keycloak (keycloak)Раздельные базы данных, резервные копии, жизненные циклы
Kafkaобщий кластер gStack (целевой вариант — Strimzi; один broker в compose)Транспорт событий

2.1 Структура репозитория (govtech/gstack/gsso)

Section titled “2.1 Структура репозитория (govtech/gstack/gsso)”
gsso/
CLAUDE.md gsso.jdl gsso.dc.html test-scenarios.md .env.example
docs/reports/ 00..05 (en, ro, ru), README, docx/, pdf/, img/
keycloak/
extensions/ Maven module: gsso-kafka event listener, mappers (roles, roles_scoped, org_unit, tenant), conditional-role authenticator
themes/gstack/ login/, account/, email/ (FreeMarker + GDS CSS, messages_ro/ru/en)
realms/ gstack.json, cetatean.json, tenant-template.json (keycloak-config-cli, ${ENV} placeholders)
Dockerfile FROM keycloak:26.6.x → kc.sh build with providers + theme
gsso/ JHipster 9.1.0 microservice (generated from gsso.jdl + custom code)
gsso-gateway/ JHipster 9.1.0 gateway
gsso-web/ Angular SPA on GDS
sdk/
gsso-spring-boot-starter/
gsso-angular/
deploy/
docker-compose.yml local + demo host stack
docker-compose.test.yml postgres + kafka + keycloak for IT (always `down -v`)
nginx/gsso.conf vhost templates (applied only with owner approval)
helm/gsso/ Kubernetes target
testing/results/
Пакет (systems.esempla.gsso)КомпонентПримечания
domain, repository, service, web.restCRUD для сущностей JDL, сгенерированный JHipsterрегенерируется; собственный код находится в классах с отдельными именами
keycloakKeycloakAdminGatewayЕдинственный класс, обращающийся к keycloak-admin-client. Поиск по естественным ключам, маркер gsso.managed, преобразование ошибок в RFC 7807
syncJobOutbox, ReconcilerWorker, RealmDiffer, DriftPolicyЗадания outbox, worker с FOR UPDATE SKIP LOCKED + advisory lock на каждый realm, периодическое полное сравнение
sync.handlersRealmHandler, ClientHandler, RoleHandler, RoleMappingHandler, UserHandler, PolicyHandler, OrgUnitHandlerОдин обработчик на тип объекта: apply(job), diff(realm)
grantGrantLifecycleService, GrantExpiryScheduler, ApprovalPolicyМашина состояний, принцип «четырёх глаз», истечение срока, уведомления
eventsKcEventConsumer, EventStore, HashChain, GlogRelay, RevocationPublisherИдемпотентное потребление, хранилище только для добавления (append-only), пересылка, исходящие события
projectionUserProjectionUpdater, NightlyUserSyncProiectieUtilizator
reportDashboardAggregator, AccessReportKPI, корзины входов, структура способов аутентификации
web.rest.admin, web.rest.appФасадные контроллерыЗоны, scope, фильтр ограничения по realm, хранилище Idempotency-Key
securityRealmScopeAuthorizationManager, PlatformScopeAuthorizationManagerОграничение области GSSO_REALM_ADMIN/GSSO_PLATFORM_OWNER
notifyGnotifyClientПредупреждения об истечении срока, оповещения
erDiagram
REALM ||--o{ CLIENT_APLICATIE : "содержит"
REALM ||--|| POLITICA_AUTENTIFICARE : "имеет"
REALM ||--o{ UNITATE_ORGANIZATIONALA : "имеет"
REALM ||--o{ PROIECTIE_UTILIZATOR : "проецирует"
PLATFORMA ||--o{ CLIENT_APLICATIE : "владеет"
PLATFORMA ||--o{ ROL_PLATFORMA : "предоставляет"
PLATFORMA }o--o{ REALM : "развёрнута в"
ROL_PLATFORMA ||--o{ ROL_PLATFORMA : "составная из"
PACHET_ROLURI }o--o{ ROL_PLATFORMA : "объединяет"
ATRIBUIRE_ACCES }o--|| ROL_PLATFORMA : "предоставляет"
ATRIBUIRE_ACCES }o--o| PACHET_ROLURI : "через пакет"
ATRIBUIRE_ACCES }o--o| UNITATE_ORGANIZATIONALA : "ограничена"
ATRIBUIRE_ACCES ||--o{ APROBARE : "согласована"
UNITATE_ORGANIZATIONALA ||--o{ UNITATE_ORGANIZATIONALA : "родитель"
JOB_SINCRONIZARE }o--|| REALM : "нацелено на"
EVENIMENT_GSSO }o--|| REALM : "в"

Определяющим является gsso.jdl. Основные поля:

СущностьКлючевые поляПримечания
Realmnume (уникальное), denumireAfisata, tip {STAFF, CETATEAN, TENANT, SERVICE}, brokerAlias, politicaDrift {REPORT, ENFORCE, IGNORE}, stare {ACTIV, INACTIV}, stareSync, kcId, adoptat
Platformacod (уникальное), denumire, tip {SAAS, PAAS}, descriere (ro/ru/en), urlBaza, accent, stare, autoInregistrareвладельцы через ProprietarPlatforma(sub)
ClientAplicatieclientId, protocol {OIDC, SAML}, tipAcces {PUBLIC_PKCE, CONFIDENTIAL, BEARER_ONLY, SERVICE_ACCOUNT}, redirectUris, webOrigins, postLogoutUris, backchannelLogoutUrl, audienta, scopuri, audienteSchimb, sensibil, stare, stareSync, kcIdуникально по (realm, clientId)
RolPlatformacod (с префиксом, уникальное в пределах realm), descriereRo/Ru/En, compozit, sensibil, valabilitateImplicitaZile, stareSync, kcIdдочерние роли через связь с самой собой
PachetRoluricod, denumire, ролисинхронизируется как группа Keycloak
AtribuireAccesuserSub, realm, rol / pachet, unitate, validDe, validPana, stare {SOLICITATA, APROBATA, ACTIVA, RESPINSA, REVOCATA, EXPIRATA}, solicitant, motiv, sursa {CONSOLA, APP, ADOPTAT, DIRECT}, motivRevocare
Aprobareatribuire, aprobator, nivel (1/2), decizie, comentariu, data
UnitateOrganizationalacod, denumire (ro/ru/en), parinte, sefi
PoliticaAutentificareparola, otp, webauthn, qr, client, broker, magic (булевы), politicaParola, mfaRoluriSensibile, sesiuneInactivMin, sesiuneMaxOre, tokenAccesMinодна на realm
JobSincronizarerealm, tipObiect, cheieObiect, operatie {CREATE, UPDATE, DELETE, MAP, UNMAP, DIFF}, stare {PENDING, RUNNING, OK, FAILED, DRIFT, ACCEPTAT}, incercari, urmatoareaIncercare, eroare, diff (jsonb), corelatie
ProiectieUtilizatorsub, realm, username, nume, email, idnpCriptat, activ, mfa (множество), ultimaAutentificare, ultimulEsec, unitate, locale, actualizatLaмодель чтения
EvenimentGssoid (UUID), realm, tip, categorie {KC_USER, KC_ADMIN, CATALOG, GRANT, SYNC, CONSOLE}, actor, subiect, client, ip, moment, payload (jsonb), hashPrecedent, hash, glogIdтолько добавление (append-only); ежемесячные партиции

Столбцы JSONB (diff, payload, descriere) объявлены в JDL как TextBlob и преобразуются дополнительным changelog Liquibase с @JdbcTypeCode(SqlTypes.JSON). Changelog-и только дополняются (append-only).

5.1 Регистрация платформы → клиенты и роли в Keycloak

Section titled “5.1 Регистрация платформы → клиенты и роли в Keycloak”
sequenceDiagram
actor A as Администратор платформы
participant W as gsso-web
participant G as gsso-gateway
participant S as gsso
participant DB as БД gsso
participant R as ReconcilerWorker
participant K as Keycloak
A->>W: Создать платформу "crm" + клиенты + роли
W->>G: POST /api/v1/admin/platforme (Idempotency-Key)
G->>S: ретрансляция (token пользователя)
S->>DB: tx: Platforma, ClientAplicatie*, RolPlatforma*, JobSincronizare*, EvenimentGsso
S-->>W: 201 (stareSync=PENDING)
R->>DB: взять задания (SKIP LOCKED, блокировка realm)
R->>K: GET client по clientId → отсутствует → POST client (gsso.managed=true)
R->>K: POST роли, составные роли, audience mapper
R->>DB: задание OK, kcId сохранён, stareSync=IN_SYNC, событие SYNC_OK
W->>G: опрос / обновление → значок "синхронизировано"

5.2 Запрос доступа → согласование → token

Section titled “5.2 Запрос доступа → согласование → token”
sequenceDiagram
actor Req as Заявитель
actor Own as Владелец платформы
actor Ap2 as Согласующий (чувствительная роль)
participant S as gsso
participant K as Keycloak
participant N as GNotify
Req->>S: POST /admin/atribuiri {sub, CRM_ADMIN, motiv}
S->>S: SOLICITATA (+событие)
S->>N: уведомить владельца
Own->>S: согласовать (уровень 1)
alt чувствительная роль
Ap2->>S: согласовать (уровень 2, ≠ заявитель, ≠ согласовавший владелец)
end
S->>S: APROBATA + задание MAP
S->>K: добавить role-mapping (reconciler)
K-->>S: 204
S->>S: ACTIVA (+событие, gsso.grant.v1)
Note over K: следующий token пользователя содержит CRM_ADMIN в roles
sequenceDiagram
actor O as Владелец
participant S as gsso
participant K as Keycloak
participant Kf as Kafka
participant App as Приложение (starter)
O->>S: отозвать доступ (motiv)
S->>K: удалить role-mapping
S->>K: POST /users/{id}/logout (сессии + back-channel logout)
S->>Kf: gsso.access-revoked.v1 {sub, notBefore=now}
Kf->>App: deny-list для sub до истечения TTL token
App-->>App: запросы с iat < notBefore → 401
S->>S: REVOCATA (+событие → GLog)

5.4 Событие входа → дашборд и GLog

Section titled “5.4 Событие входа → дашборд и GLog”
sequenceDiagram
participant U as Пользователь
participant K as Keycloak (+gsso-kafka)
participant Kf as Kafka
participant S as gsso
participant L as GLog
U->>K: вход (пароль + OTP)
K-->>U: token
K--)Kf: событие LOGIN (асинхронно)
Kf->>S: потребление (дедупликация eventId)
S->>S: EvenimentGsso (hash chain), projection.lastLogin, агрегаты
S->>L: POST /api/v1/app/audit-events (client credentials)
L-->>S: id квитанции

5.5 Полная синхронизация и drift

Section titled “5.5 Полная синхронизация и drift”
  1. Каждые 15 мин или по запросу RealmDiffer загружает желаемое состояние realm и считывает Keycloak (клиенты, роли, составные роли, сопоставления управляемых ролей, группы, flow и поля политик, которыми он управляет).
  2. Для каждого расхождения создаётся JobSincronizare(DIFF):
    • отсутствует в Keycloak → CREATE (если политика ENFORCE) или DRIFT;
    • отличается → UPDATE или DRIFT;
    • присутствует в Keycloak с gsso.managed=true, но отсутствует в GSSO → DELETE или DRIFT;
    • присутствует без маркера → NEGUVERNAT (только отчёт).
  3. В консоли администратор может повторить, принудительно применить (применить значение GSSO) или принять drift (скопировать значение Keycloak в GSSO).

5.6 Принятие под управление существующего realm (например, interdictii)

Section titled “5.6 Принятие под управление существующего realm (например, interdictii)”

Сначала выполняется пробный прогон (dry run, GSSO-FR-080), затем импорт:

  • клиенты группируются в платформы по файлу сопоставления (clientId → код платформы);
  • роли realm сопоставляются с ролями платформ по правилам переименования (например, ROLE_ADMIN → кандидаты <APP>_ADMIN для каждой платформы, помеченные для проверки);
  • текущие сопоставления пользователь→роль становятся AtribuireAcces(ACTIVA, sursa=ADOPTAT).

Пока политика drift имеет значение IGNORE, в Keycloak ничего не записывается.

  1. Браузер открывает gsso.gstack…, и gsso-gateway перенаправляет его в Keycloak (realm gstack, клиент gsso-console, PKCE + confidential).
  2. Пользователь входит в систему. MFA обязательна для любой роли GSSO_* (NFR-SEC-008).
  3. Шлюз сохраняет token в серверной сессии и устанавливает cookie SESSION (HttpOnly, Secure, SameSite=Lax), а также cookie CSRF.
  4. Вызовы SPA передают cookie. Шлюз ретранслирует access token в gsso, который применяет ограничение области по realm и платформе на основании ролей GSSO_* и их атрибутов.

5.8 Вход гражданина через MPass

Section titled “5.8 Вход гражданина через MPass”
  1. Клиент cetatean перенаправляет гражданина в Keycloak, который выступает broker к MPass (SAML POST).
  2. Возвращается assertion. Flow first-broker-login ищет пользователя по атрибуту IDNP; если пользователь найден, учётная запись связывается, иначе пользователь создаётся с сопоставленными атрибутами.
  3. Keycloak устанавливает значение acr по уровню доверия MPass, и token выпускается для портала.

6. Базовая конфигурация realm (keycloak/realms/gstack.json, кратко)

Section titled “6. Базовая конфигурация realm (keycloak/realms/gstack.json, кратко)”
ПараметрЗначение
Тема входа / учётной записи / emailgstack (GDS), локали ro, ru, en, по умолчанию ro
Защита от подбора (brute force)включена, 5 неудачных попыток, приращение ожидания 60 с, максимум 15 мин
Политика паролейlength(12) and upperCase(1) and lowerCase(1) and digits(1) and notUsername and notEmail and passwordHistory(5)
Простой / максимум сессии SSO30 мин / 10 ч
Access token5 мин
Событиявключены пользовательские и административные события, административные события с представлением, слушатели jboss-logging, gsso-kafka, срок хранения 7 дней
Client scopes (по умолчанию)profile, email, gsso-roles (плоский список ролей), gsso-org (org_unit, org_unit_path, roles_scoped), gsso-locale, acr
Client scopes (опциональные)idnp, gsso-roles-filtered, offline_access
Browser flowCookie (alt) → Identity provider redirector (alt) → Forms: username+password (req) → Conditional OTP/WebAuthn (условие: у пользователя есть роль GSSO_MFA_REQUIRED или любая роль, помеченная как чувствительная)
Роли по умолчаниюROLE_USER
Базовые клиентыgsso-console (confidential, standard flow, PKCE), gsso-api (bearer), gsso-reconciler находится в master
Обязательные действияподтверждение e-mail, смена пароля, настройка OTP, регистрация WebAuthn, условия использования (отключено)
Token exchangeвключён стандартный token exchange V2; разрешения для каждого клиента — из GSSO

cetatean.json использует ту же тему и другие параметры:

  • SAML identity provider MPass с flow first-broker-login, сопоставляющим по IDNP;
  • без LDAP;
  • вход по паролю по умолчанию отключён;
  • простой сессии 15 мин.

tenant-template.json — параметризованная копия gstack без федерации.

АспектМера
Доступ к консолиBFF; роли GSSO_*; обязательная MFA; простой 15 мин; CSRF; CSP
Ограничение по realmGSSO_REALM_ADMIN несёт атрибут gsso.realm; серверный фильтр для каждого запроса и команды; проверяется матрицей авторизации
Ограничение по платформеGSSO_PLATFORM_OWNER с атрибутом gsso.platforma (многозначным)
ReconcilerСервисная учётная запись в master только с ролями manage-*/view-* управляемых realm (fine-grained admin permissions V2); учётные данные в хранилище секретов; ротация каждые 90 дней
Принцип «четырёх глаз»ApprovalPolicy: заявитель ≠ согласующий; для чувствительных ролей — два разных согласующих; сами роли GSSO являются чувствительными
СекретыСекреты клиентов генерируются Keycloak, показываются в консоли один раз и не сохраняются в БД GSSO
Персональные данныеIDNP зашифрован (AES-GCM, ключ из хранилища секретов) и маскируется; журналы очищаются
Целостность событийHash chain + триггер БД + копия WORM в GLog
КлючиКлючи realm RS256, ротация каждые 90 дней с перекрытием (новый — активный, старый — пассивный до истечения максимального TTL token)
Цепочка поставокSBOM (CycloneDX), Trivy, Semgrep, Gitleaks через /gsast; образ Keycloak собирается из зафиксированного digest

Роли консоли GSSO (realm gstack):

РольЧувствительная
GSSO_ADMINда
GSSO_REALM_ADMINда
GSSO_PLATFORM_OWNERда
GSSO_APPROVERда
GSSO_HELPDESKда
GSSO_AUDITORнет
GSSO_IDNP_VIEWда
GSSO_MFA_REQUIREDмаркер

8.1 Демо-хост (текущее соглашение gStack)

Section titled “8.1 Демо-хост (текущее соглашение gStack)”
  • Стек compose ~/devops/gsso/ на общем хосте. Контейнеры подключаются к внешней сети gstack-web.
  • Работающие контейнеры keycloak + postgres-keycloak принимаются под управление (§11.1): стандартный образ заменяется образом GSSO, собранным на той же версии с добавленными расширениями и темой.
  • gsso, gsso-gateway, gsso-web, gsso-postgres и, если общий Kafka недоступен, одноузловой Kafka (KRaft).
  • vhost:
    • sso.gstack.esempla.systems → keycloak:8080, как сейчас;
    • новый gsso.gstack.esempla.systems → gsso-web + gateway. Любое изменение периметрового nginx требует согласования владельца, а продление сертификатов должно быть исправлено в первую очередь (NFR-AVL-006).
  • Процесс развёртывания: сборка образов amd64 → push в registry.esempla.systems/govtech/gstack/gsso-* (или docker save | ssh | docker load) → docker compose up -d --no-deps --force-recreate <svc>.
  • Бюджет памяти на хосте ≈ 8 ГБ:
    • Keycloak — heap 1 ГБ;
    • gsso — 512 МБ;
    • gateway — 384 МБ;
    • postgres ×2 — по 256 МБ;
    • Kafka — 512 МБ, если локальный.

8.2 Целевой вариант Kubernetes (Helm)

Section titled “8.2 Целевой вариант Kubernetes (Helm)”
  • Keycloak: 2 реплики (кластер Infinispan через Kubernetes DNS_PING), с PDB и HPA по CPU.
  • gsso: 2 реплики. Reconciler является единственным экземпляром на realm благодаря advisory lock, поэтому могут работать обе реплики.
  • gateway: 2 реплики, сессии в Redis или JDBC.
  • PostgreSQL: CloudNativePG, по 2 экземпляра.
  • Kafka: общий кластер Strimzi.
ПоказательОценка
Пользователи-сотрудники5 000 (начально) → 20 000
Пиковое число входов50/мин типично, всплеск 10/с в 9:00
Событий в день≈ 50 000 (входы, обновление token по умолчанию не журналируется, административные) → ≈ 30 МБ/день jsonb → партиции за 90 дней ≈ 3 ГБ
БД GSSO< 10 ГБ в первый год
БД Keycloak< 5 ГБ (сессии в памяти, функция persistent user sessions включена в 26.x → +1 ГБ)
  • Метрики (Micrometer → Prometheus):
    • gsso_sync_jobs{state}, gsso_reconcile_seconds, gsso_drift_total, gsso_event_lag_seconds, gsso_glog_lag_seconds;
    • Keycloak keycloak_logins_total, keycloak_failed_login_attempts_total (metrics SPI);
    • метрики JVM и HTTP.
  • Журналы: JSON с trace id; фильтр очистки для Authorization, access_token, client_secret, password, idnp.
  • Трассировка: OpenTelemetry по цепочке gateway → gsso → административные вызовы Keycloak.
  • Оповещения: NFR-OBS-004, маршрутизируются через GNotify.

11. Эксплуатационный runbook (структура)

Section titled “11. Эксплуатационный runbook (структура)”

11.1 Принятие под управление работающего Keycloak

Section titled “11.1 Принятие под управление работающего Keycloak”
  1. Получить согласование владельца и согласовать окно работ. Сначала исправить продление TLS.
  2. Выполнить pg_dump базы данных Keycloak и скопировать дамп за пределы хоста. Экспортировать каждый realm (kc.sh export --realm … --users different_files) для справки.
  3. Собрать образ Keycloak GSSO на той же версии (26.6.3) с добавленными расширениями и темой. Базовая конфигурация пока не применяется.
  4. Заменить образ и проверить:
    • входы для всех приложений;
    • issuer не изменился;
    • JWKS не изменился. Откат = предыдущий образ, та же база данных.
  5. Включить слушатель gsso-kafka в realm interdictii (административное действие), затем запустить gsso с realm interdictii принятым под управление, IGNORE.
  6. Применить базовые конфигурации gstack и cetatean (новые realm; ничего существующего не меняется).
RunbookШаги
Обновление KeycloakРезервное копирование базы данных → прогон набора IT базовой конфигурации + reconciler на новом образе → поэтапное развёртывание → smoke-тест
Ротация ключейДобавить новый ключ RS256 (более высокий приоритет) → подождать не менее 1 TTL token + обновление → сделать старый ключ пассивным → удалить его по истечении максимальной сессии
Ротация секрета клиента«Ротация» в консоли → окно с двумя действующими секретами → повторное развёртывание приложения → старый секрет аннулируется
Break-glassИспользовать аварийного администратора master (запечатанные учётные данные, правило двух лиц); о каждом использовании составляется отчёт
ВосстановлениеВосстановить базу данных Keycloak из резервной копии → выполнить полную синхронизацию в режиме REPORT → проанализировать drift → ENFORCE
СертификатПродление через webroot; оповещение за 21 день; ежемесячное проверочное задание

12. Стратегия тестирования

Section titled “12. Стратегия тестирования”
УровеньОхватИнструменты
МодульныйМашина состояний предоставления доступа, политика согласования, differ, hash chain, mappers, сопоставление в starterJUnit 5, AssertJ
ИнтеграционныйReconciler с реальным Keycloak, слушатель событий → Kafka → потребитель, Liquibase + триггер append-onlyTestcontainers (Keycloak 26.6.x с расширениями, PostgreSQL, Kafka) и deploy/docker-compose.test.yml (всегда down -v)
КонтрактныйOpenAPI api/v1/app, схемы событий (CloudEvents + JSON Schema)api_audit.py, тесты схем
E2EПотоки консоли (регистрация платформы, пользователь, согласование доступа, отзыв, drift), SSO между двумя демонстрационными приложениями, mock MPassCypress
БезопасностьМатрица авторизации (ограничение по realm/платформе, принцип «четырёх глаз»), базовый ZAP, заголовки, SAST/SCA/секреты/gtestgen, /gtest, /gsast
ПроизводительностьВсплеск входов, списки консоли, синхронизация 1 000 клиентов/load-test, k6 для Keycloak
Проверка UIНеработающие элементы управления, непереведённые ключи, доступность (a11y)/gfront

Тестовые сценарии перечислены в test-scenarios.md (TS-GSSO-NN) и повторно используют общие случаи TC-COM-*.

СтатьяОценка
Демо-хостРазмещается на существующем хосте (≈ 3 ГБ дополнительной RAM)
Целевой вариант Kubernetes3 vCPU / 6 ГБ requests (Keycloak 2×, gsso 2×, gateway 2×) + 2 кластера PostgreSQL
Трудозатраты на разработку (S0–S3)≈ 14–18 человеко-недель (1 backend, 1 frontend, 0,5 Keycloak/DevOps)
Миграция существующих приложений (S4)≈ 1–2 человеко-недели на приложение шаблона A, ≈ 0,5 на приложение шаблона B