Перейти к содержанию

Общие соглашения

Де-факто стандарты, которые повторяются во всех репозиториях экосистемы. Они выросли не из формальной спецификации — это правила, устоявшиеся после того, как одни и те же реальные проблемы были решены по нескольку раз. Новая платформа должна следовать им с самого начала.

Identity casing

Правило: хранить весь текст идентичности в базе данных в нижнем регистре. Поиск регистронезависим. К отображению приводить в стандартный вид (регистрационные номера — в верхнем регистре, имена — Title Case).

Поля-исключения — они хранятся ровно так, как получены:

Поле Почему
etsi_identifier Формат задан стандартом
DN сертификата Входит в криптографическую подпись, изменять нельзя
Поля *_latin Латинская транслитерация — сохраняет исходный вид
document_number Номер официального документа
Значения хеша Значим каждый бит

Откуда взялось это правило

Гражданин регистрировался как АБ12345678, а затем пытался войти как аб12345678 — система видела другого человека, и появлялась дублирующая учётная запись. Нормализация регистра на уровне хранения убирает весь этот класс ошибок.

Иерархия ролей

superadmin (1) → admin (2) → manager (3) → user (4)

Жёсткие правила:

Роль Может НЕ может
superadmin Добавлять/удалять учётные записи admin
admin Выдавать права manager Управлять учётными записями admin
manager Повседневные операции Добавлять людей
user Собственные действия Выдавать права

Super admin — отдельная учётная запись с MFA. Создаётся через onboarding-мастер: allow-list приглашений → Google → eID → OTP по почте → TOTP + коды восстановления. Хранится в отдельной таблице с ключом по Google-идентичности.

Практическое следствие: один человек может быть и админом по eID, и Google super admin — две разные учётные записи, два разных входа. Каждый вход super admin защищён MFA.

Права admin выдаются по регистрационному номеру, против пользователя, зарегистрированного в локальном eID.

Выдача прав, подтверждённая подписью

Правило: при выдаче кому-либо прав manager в организации этому человеку уходит eID SIGN push, и права становятся ACTIVE только после подтверждения через PIN2.

Почему: выдача прав — действие с юридическими последствиями. Если администратор в одностороннем порядке сделал кого-то руководителем, тот может впоследствии это отрицать. Подпись PIN2 обеспечивает неотрекаемость и закрывает возражение «я на это не соглашался».

Правила callback

Правило: callback возвращается только в same-device потоках. Во всех остальных случаях сессия опрашивается (poll).

Ситуация Механизм
Пользователь на одном устройстве (deep-link) Callback
QR-код — второе устройство Опрос сессии (long-poll)
Push-уведомление Опрос сессии

Причина: в потоке, начатом на другом устройстве, callback не знает, куда возвращаться. Опрос делает исходный браузер источником истины и оставляет поток однозначным.

Deep-link третьей стороны — передаётся параметром callback; по завершении соответствующее приложение выводится на передний план.

Привязка Google

Правило: перед привязкой Google-аккаунта пользователь обязан пройти проверку через eID. Первая привязка связывает аккаунт с реальным человеком; дальше можно входить прямо через Google. Отвязка возможна.

Причина: Google-аккаунт может создать кто угодно. Сам по себе он не может приниматься как идентификация гражданина. После однократной привязки через eID этот Google-аккаунт указывает на конкретного гражданина.

RP ↔ rp_app

Правило: в eID регистрируется только RP. Несколько приложений или подсистем под одним RP передаются через поля rp_app / rp_app_url.

Тогда в логах и на экране пользователя видно, какое приложение сделало запрос, — без регистрации отдельного RP на каждое приложение и без раздачи credential по сторонам.

Выход завершается на том домене, где начался

Правило: при выходе пользователь возвращается на тот домен, с которого начал, а не выбрасывается на /login в SSO.

Почему: пользователь находился в приложении RP. Оказаться после выхода на странице входа совершенно незнакомого домена — дезориентирует. Выход должен завершаться внутри того приложения, в котором начался.

У credential один источник

Правило: OAuth-клиенты и client secret создаются только в SSO и живут только там. Никакая другая система их не создаёт, не хранит и не показывает.

Developer Portal — проверочный пример этого правила: он даёт инструкции по регистрации приложения, но не создаёт клиентов, а лишь даёт глубокую ссылку в консоль SSO.

Документация — это код

Правило: у каждого репозитория свой каталог docs/ и сайт MkDocs. Документация живёт в том же репозитории, что и код, и меняется вместе с ним в одном PR.

Языковой охват: как минимум MN + EN; в основных репозиториях добавляются ZH · RU. Подробности — на странице Многоязычность.

Clean Architecture — без обратных импортов

Правило: handler → usecase → repository → domain. Зависимости идут только в одну сторону. Бизнес-ядро (domain, usecase) никогда не импортирует веб-фреймворк.

Простая проверка: если в файле внутри domain/ есть импорт net/http или chi, правило нарушено.

Чек-лист для добавления новой платформы

  • [ ] Аутентификация — через SSO как OIDC RP, собственной системы паролей нет
  • [ ] Иерархия ролей superadmin → admin → manager → user
  • [ ] Текст идентичности в БД в нижнем регистре, поля-исключения определены
  • [ ] Postgres RLS включён + boot-time enforceability guard
  • [ ] Журнал аудита — связанный хеш-цепочкой
  • [ ] Security-заголовки, allow-list CORS и rate limit настроены
  • [ ] /metrics, /swagger закрыты в production
  • [ ] docs/ + сайт MkDocs, MN/EN
  • [ ] CI: сборка + тесты + строгая проверка документации