Skip to content

GSSO — Потребители и контракт потребителя

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

1. Текущие схемы интеграции

Section titled “1. Текущие схемы интеграции”
СхемаОписаниеПроблема
A — двойная аутентификация с выпуском собственного tokenoauth2Login через Keycloak, затем OidcAppTokenSuccessHandler выпускает собственный JWT приложения HS512 (копируя ROLE_*) и возвращает его SPA через /oidc-callback#id_token=. Локальный вход admin/admin по-прежнему работаетЛокальный ключ подписи и пароли; нет SSO-выхода; отзыв в Keycloak не действует; два источника идентичности
B — resource serverПриложение проверяет token RS256 Keycloak через issuer/JWKS; SPA использует PKCE или OAuth2 JHipsterКорректно, но у каждого приложения свой код и своё сопоставление ролей
C — локальный JWT (+ MPass SAML)Собственные пользователи и пароли; MPass через SAML непосредственно в приложенииНет SSO с gStack
D — спроектировано, не реализованоПриложения по playbook: шлюз BFF + микросервисы с OAuth2 через GSSOТребуются CAP-GSSO-01..07

Цель для всех: GSSO-ADR-009. Это означает шлюз/BFF или resource server через gsso-spring-boot-starter, SPA через @gstack/gsso-angular и отсутствие локальных паролей и самостоятельно выпускаемых token.

2. Перечень потребителей и миграция

Section titled “2. Перечень потребителей и миграция”

Realm interdictii — текущий общий realm. «Целевой» означает realm gstack, если не указано иное.

ПриложениеВидСегодня (realm / клиент / схема)Целевые клиентыЦелевые роли (примеры)Примечания к миграцииФаза
saas_interdictiiSaaSinterdictii / interdictii-web confidential / A (незакоммиченный ручной патч, JHipster 8.11 jwt)interdictii-web (confidential, BFF) или interdictii-spa (PKCE) + interdictii-api (bearer)INTERDICTII_ADMIN, INTERDICTII_EMITENT, INTERDICTII_APROBATOR, INTERDICTII_CONSULTANT, INTERDICTII_AUDITORЗаменить OidcAppTokenSuccessHandler на resource server через starter; убрать локальные пароли; сопоставить RolUser ADMIN/EMITENT с ролями; публичный API консультаций → сервисные клиенты для банков/ANAF в realm tenant- или gstackS4
cancelarieSaaSinterdictii / cancelarie confidential / B (JHipster oauth2, собственная подготовка учётных записей в identity/)cancelarie (confidential), cancelarie-apiCANCELARIA_REGISTRATOR, _SEF, _EXECUTOR, _CONTROLOR, _AUDITOR, _ADMINПодключение сотрудников вызывает запросы на предоставление доступа api/v1/app (GSSO-FR-051) вместо локального допуска; локальный dev-realm jhipster заменяется compose-стеком GSSOS4
gregistrySaaSinterdictii / gregistry-web public PKCE / B (ADR-002)идентификаторы без изменений, перенесены в gstackGREGISTRY_ADMIN, GREGISTRY_OPERATORПилот starter (уже схема B); сохраняет только локальный выход, пока не потребуется единый выход (single logout)S3
gdocsSaaSgdocs (профиль oidc) / gdocs-web / Agdocs-web, gdocs-api, gdocs-serviceGDOCS_ADMIN, GDOCS_EDITOR, GDOCS_CITITORКак для interdictii; realm gdocs выводится из эксплуатацииS4
saas_drumuriSaaSлокальный JWT + MPass SAML в приложении / env фронтенда ошибочно указывает на glog-web / Cсотрудники: drumuri-web в gstack; граждане: drumuri-public в cetateanDRUMURI_ADMIN, DRUMURI_OPERATOR, DRUMURI_INSPECTORMPass переносится из приложения в брокер cetatean; немедленно исправить env фронтенда (неверный client id); отдельный хост routes.tech.esempla.systems → redirect URIS4
saas_crmSaaSтолько проект / Dcrm-gateway (confidential), по одному сервисному клиенту на микросервис (crm-core, crm-clienti, crm-comercial, crm-interactiuni, crm-suport, crm-contracte, crm-operational, crm-taskuri, crm-strategie, crm-integrare, crm-cautare, crm-ai), crm-integration-1cCRM_* (из отчёта CRM 02)CAP-GSSO-01 — блокер для CRM F0; token exchange в gDocFlow/gTenders (CAP-GSSO-07)S1–S3
saas_gdocflowSaaSпроект / Dgdocflow-gateway, сервисные клиентыGDOCFLOW_*Цель и источник token exchangeS3
saas_gtendersSaaSпроект / Dgtenders-gateway, сервисные клиентыGTENDERS_*Token exchangeS3
saas_gnotifySaaS/PaaSrealm gnotify (не создан) / OIDC отключён / A; использует учётные данные клиента glog-ingestgnotify-web, gnotify-serviceGNOTIFY_ADMIN, GNOTIFY_OPERATOR; scope notify:send для вызывающих сторонВключить через starter; GSSO использует GNotify через scope gnotify-serviceS4
glogPaaSinterdictii / glog-web PKCE (жёстко заданный mapper tenant=demo) + сервис glog-ingest / B (профиль dualauth)glog-web, glog-api, ingest-клиенты для каждой вызывающей стороны (<app>-glog)GLOG_ADMIN, GLOG_AUDITOR; client scope audit:write, audit:readЗаменить сопоставление роль→scope в GlogJwtAuthConverter на starter + явные scope; claim tenant из mapper GSSO; сам GSSO становится ingest-клиентомS3
paas_gstoragePaaSrealm gstorage / gstorage-web, gstorage-ingest; альтернатива — API-ключgstorage-web, gstorage-api, сервисные клиенты <app>-gstorageGSTORAGE_ADMIN, GSTORAGE_ARCHIVIST; scope `storage:readwriteadmin`
paas_gflowPaaSпроект / Dgflow-gateway, gflow-server, сервисные principal для каждого приложения (<app>-gflow)GFLOW_ADMIN; группы-кандидаты = роли потребителейИспользует GET /api/v1/app/roluri/{cod}/utilizatori (GSSO-FR-103); без token exchangeS3
gportal / GDSPaaSбез аутентификации (заглушки)gportal-web (PKCE)ROLE_USERИспользует @gstack/gsso-angularS4
platform (docs/RAG)внутреннееinterdictii / gstack-platform PKCE; Python PyJWT + JWKS, требует ROLE_ADMINgstack-platformPLATFORM_ADMINИзменить проверку роли с ROLE_ADMIN на PLATFORM_ADMINS4
gsso_mob (GovSign)мобильноеrealm gstack / gstack-govsign-app public PKCE, redirect com.govsign.app://callback; подтверждение по QR для каждого сайтаgovsign-app (public PKCE) в gstack и cetateanROLE_USERУдалить KEYCLOAK_CLIENT_SECRET из конфигурации публичного клиента; вход по QR как аутентификатор Keycloak (GSSO-FR-068)S5
Сайты whitelabel (ultra-b2b, ultra-ecom, bts-licitatii, bts-integrare, esempla-govstec, esempla-sistembancar)сайтыrealm ultra / gstack-ultra (не подтверждено)по одному realm tenant-<code> на сайт, из шаблонадля каждого сайтаСоздаются через GSSO из шаблона; endpoint подтверждения по QR сохраняется до GSSO-FR-068S4
qa_platformинструментнет (только целевые учётные данные)сервисный клиент qa-runner для каждого окруженияQA_RUNNERТестовые пользователи создаются через API GSSO в непродуктивных realmS5

2.1 Порядок миграции приложения со схемой A

Section titled “2.1 Порядок миграции приложения со схемой A”
  1. Зарегистрировать платформу, клиентов и роли в GSSO или принять их из interdictii (GSSO-FR-007).
  2. Создать предоставления доступа, воспроизводящие текущих обладателей ролей (AtribuireAcces с источником ADOPTAT).
  3. Добавить gsso-spring-boot-starter. На переходный период задать gsso.issuer-uri, gsso.audience и gsso.role-aliases (например, ROLE_ADMIN: INTERDICTII_ADMIN).
  4. Удалить обработчик выпуска собственных token, локальный секрет JWT, локальный вход по паролю и маршрут /oidc-callback. Для SPA монолита перейти на @gstack/gsso-angular в режиме BFF или PKCE.
  5. Прогнать E2E-тесты приложения на compose-стеке GSSO, затем развернуть за feature flag, который на один релиз сохраняет старый клиент параллельно.
  6. Удалить role-aliases и устаревшее сопоставление ROLE_ADMIN, затем удалить старый клиент.

Базовый путь: https://gsso.gstack.esempla.systems/api/v1 (через gsso-gateway).

Соглашения:

  • JSON, ошибки по RFC 7807;
  • Idempotency-Key в каждом POST;
  • постраничная выдача через page, size, sort и X-Total-Count в ответе;
  • имена полей предметной области — на румынском.

3.1 Зона app — приложения-потребители (client credentials, scope gsso:app)

Section titled “3.1 Зона app — приложения-потребители (client credentials, scope gsso:app)”
МетодПутьНазначениеТреб.
GET/app/platformaсобственная платформа с клиентами и ролямиFR-098
PUT/app/platformaсамостоятельная регистрация / обновление собственной платформы, клиентов, ролей (только для помеченных клиентов)FR-099
GET/app/utilizatori?sub=&username=&email=&idnp=поиск (IDNP — только при наличии разрешения)FR-100
GET/app/utilizatori/{sub}статус (enabled, MFA, последний вход), имя, e-mail, организационная единица, localeFR-101
GET/app/utilizatori/{sub}/roluriэффективные роли вызывающей платформы с областями действия и сроком действияFR-101
DELETE/app/utilizatori/{sub}/sesiuniзавершить сессии пользователяFR-102
GET/app/roluri/{cod}/utilizatoriпользователи, имеющие роль вызывающей платформы (постранично)FR-103
POST/app/atribuiriзапросить предоставление доступа пользователю на вызывающей платформе ({sub, rol, orgUnit?, validPana?, motiv}) → SOLICITATAFR-051
GET/app/atribuiri/{id}статус предоставления доступаFR-051

3.2 Зона admin — консоль (пользовательская сессия через gsso-gateway)

Section titled “3.2 Зона admin — консоль (пользовательская сессия через gsso-gateway)”

Ниже перечислены ресурсы; полная спецификация OpenAPI — по адресу /api/v1/openapi.json:

  • /admin/realms, /admin/realms/{realm}/adoptie, /admin/realms/{realm}/reconciliere
  • /admin/platforme, /admin/platforme/{cod}/clienti, /admin/platforme/{cod}/roluri
  • /admin/clienti/{id}/secret (ротация)
  • /admin/realms/{realm}/utilizatori, …/{sub}, …/{sub}/credentiale, …/{sub}/sesiuni, …/{sub}/actiuni (обязательные действия), …/{sub}/deblocare
  • /admin/atribuiri (с /{id}/aprobare, /{id}/respingere, /{id}/revocare)
  • /admin/unitati
  • /admin/realms/{realm}/politica-autentificare
  • /admin/sincronizare/joburi (с /{id}/reincercare, /{id}/acceptare-drift)
  • /admin/evenimente, /admin/evenimente/verificare-lant
  • /admin/tablou (агрегаты для панели мониторинга)
  • /admin/rapoarte/acces

3.3 Эксплуатационные endpoint

Section titled “3.3 Эксплуатационные endpoint”

/health/live, /health/ready, /metrics, /info, /api/v1/openapi.json.

ClaimСодержимоеПримечания
isshttps://sso.gstack.esempla.systems/realms/gstack
subUUID, стабильныйGSSO-FR-032
audaudience целевой платформы (одна или несколько)audience mapper для каждой платформы
azpclient id
preferred_username, name, emailпрофиль
rolesплоский массив эффективных ролей realm (с префиксом платформы) + ROLE_USERфильтруется по audience с помощью scope gsso-roles-filtered
roles_scoped{ "<ROLE>": ["<org_unit>", …] } только для предоставлений доступа с областью действияGSSO-FR-055
org_unit, org_unit_pathорганизационная единица пользователяGSSO-FR-054
localero / ru / en
idnpтолько с опциональным client scope idnpQ-GSSO-13
acr1 / 2 / 3GSSO-FR-070
act{ "sub": "<calling client>" } в token, полученных через exchangeGSSO-ADR-012
tenantкод realm для realm tenant-* (заменяет жёстко заданный mapper glog)

Срок жизни access token: 5 мин (2 мин для чувствительных клиентов). Подпись: RS256, ключи публикуются по адресу /protocol/openid-connect/certs.

<dependency>
<groupId>systems.esempla.gsso</groupId>
<artifactId>gsso-spring-boot-starter</artifactId>
</dependency>
# application.yml of a consuming service
gsso:
issuer-uri: https://sso.gstack.esempla.systems/realms/gstack
audience: crm
role-aliases: # transition only (report 03 §2.1)
ROLE_ADMIN: CRM_ADMIN
client: # optional: outgoing calls
id: crm-comercial
secret: ${GSSO_CLIENT_SECRET}
revocation:
kafka-topic: gsso.access-revoked.v1 # deny-list, GSSO-ADR-013
@PreAuthorize("hasAuthority('CRM_ADMIN')")
public void delete(...) { ... }
GssoPrincipal p = GssoPrincipal.current(); // sub, username, orgUnit, locale
RestClient docs = gsso.exchangeClient("gdocflow"); // token exchange (on-behalf-of)
RestClient glog = gsso.serviceClient("glog"); // client credentials

Angular:

provideGsso({ mode: 'bff', loginUrl: '/oauth2/authorization/oidc', logoutUrl: '/api/logout' })
// or { mode: 'pkce', issuer, clientId }
// route guard: canActivate: [gssoRole('CRM_ADMIN')]
// template: <button *gssoHasRole="'CRM_ADMIN'">…</button>

Все события — CloudEvents в бинарном режиме в Kafka, с source = gsso и subject = <realm>/<sub>.

TopicПроизводительТипПолезная нагрузка (data)Потребители
gsso.kc-events.v1расширение Keycloak gsso-kafkamd.gstack.gsso.kc.user.<TYPE> / md.gstack.gsso.kc.admin.<OPERATION>поля события Keycloak (type, realm, client, user, ip, error, details / resource type, path, representation без секретов)только gsso
gsso.access-revoked.v1gssomd.gstack.gsso.access.revoked{sub, realm, roluri[], platforme[], notBefore, motiv}starter в каждом приложении
gsso.user-changed.v1gssomd.gstack.gsso.user.changed{sub, realm, campuri[], enabled}приложения, кэширующие данные пользователей
gsso.grant.v1gssomd.gstack.gsso.grant.<STARE>{id, sub, rol, platforma, orgUnit, validDe, validPana, stare}приложения, зеркалирующие права (например, gFlow)

Ключ = <realm>:<sub>. Доставка — at-least-once, поэтому потребители должны быть идемпотентны по id. У каждой группы потребителей есть DLQ-topic <topic>.dlq.<group>.

6. Соглашения об именовании

Section titled “6. Соглашения об именовании”
ОбъектСоглашениеПример
Код платформыстрочные буквы, [a-z][a-z0-9-]*crm, interdictii, glog
Роль<PLATFORM_UPPER>_<ROLE> (дефисы заменяются на _)CRM_ADMIN, INTERDICTII_EMITENT
Клиент SPA<platform>-web (PKCE) или <platform>-gateway (BFF)glog-web, crm-gateway
Клиент бэкенда<platform>-api (bearer-only)cancelarie-api
Сервисный клиент<service> или <caller>-<callee>crm-comercial, gnotify-glog
Client scope (сервисный)<platform>:<verb> или <object>:<verb>audit:write, storage:read
Realm арендатораtenant-<code>tenant-ultra-b2b
Audienceкод платформыcrm

7. Квоты и уровень обслуживания

Section titled “7. Квоты и уровень обслуживания”
ПараметрЗначение по умолчанию
Ограничение частоты запросов API app50 запросов/с на клиента, пик 100
Самостоятельная регистрацияне более 20 клиентов и 200 ролей на платформу
Запросы на предоставление доступа от приложения1 000 в сутки на платформу
Предлагаемая доступностьKeycloak 99,9 %, консоль/API 99,5 % (NFR-AVL)
Поддержкакоманда платформы, в рабочее время; недоступность Keycloak = P1
Версионированиеapi/v1 стабилен; несовместимое изменение = v2 с параллельной работой в течение 6 месяцев

8. Чек-лист подключения нового приложения

Section titled “8. Чек-лист подключения нового приложения”
  1. Назначен владелец платформы; выбран код платформы (§6).
  2. Роли перечислены с описаниями на RO/RU/EN; чувствительные роли помечены; составные роли определены.
  3. Клиенты объявлены: тип доступа, redirect URI (точные), web origins, URL back-channel logout.
  4. Сервисные клиенты объявлены для каждого вызывающего сервиса, со scope; при необходимости перечислены цели token exchange.
  5. Платформа зарегистрирована в GSSO (через консоль или PUT /api/v1/app/platforma), её статус синхронизации — in sync.
  6. Приложение использует gsso-spring-boot-starter (и @gstack/gsso-angular). Локальных паролей и самостоятельно выпускаемых token нет.
  7. Проверка audience включена. Авторизация использует только роли платформы.
  8. Приложение подписано на gsso.access-revoked.v1 (через starter).
  9. Первоначальные предоставления доступа запрошены и одобрены; тестовые пользователи существуют в непродуктивных realm.
  10. CSP разрешает sso.gstack.esempla.systems в connect-src и form-action.
  11. E2E-тест входа проходит на compose-стеке GSSO. Проверка матрицы авторизации (/gtestgen) проходит.
  12. Приложение добавлено в §2 настоящего отчёта и в отчёт о доступе.