LEX — AI Legal Platform for Law Firms

AI-powered legal analysis platform for law firms and corporate counsel.

Features

Resources

Blog Articles

Technology

Built on AWS (EC2, Bedrock Claude AI, ALB, WAF, S3, ACM, KMS). PostgreSQL, Redis, Qdrant vector database. TypeScript, React, Node.js.

Start free — 50 credits on registration. Sign up

TECH 7 мин

Авторизация через Дiю: как мы интегрировали национальную цифровую идентификацию в юридическую платформу

Паспорт в смартфоне — теперь ключ к юридическому AI. Мы интегрировали Дiя.Подпись для авторизации: deep link на мобильном, QR-код на десктопе, ECDSA + SHA256 для хеширования, и юрист подтверждает личность тем же приложением, которым показывает документы на блокпосте. Без паролей. Без регистрации. Один тап — и вы в системе.

Авторизация через Дiю: как мы интегрировали национальную цифровую идентификацию

Паспорт в смартфоне — теперь ключ к юридическому AI.


Почему Дiя, а не ещё один OAuth

Юридическая платформа работает с конфиденциальными данными. Google OAuth подтверждает, что у вас есть Gmail. Дiя подтверждает, что вы — это вы. Разница принципиальная: Дiя привязана к реальному документу — паспорту, ID-карте или квалифицированной электронной подписи.

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

Архитектура: два потока

Мобильный (deep link)

  1. Пользователь нажимает «Войти через Дiю»
  2. Бэкенд генерирует requestId (ECDSA + SHA256, base64)
  3. Открывается deep link diia:// с параметрами сессии
  4. Приложение Дiя показывает запрос на авторизацию
  5. Пользователь подтверждает → Дiя отправляет callback с данными
  6. Бэкенд верифицирует подпись, создаёт JWT-сессию

Десктоп (QR-код)

  1. Бэкенд запрашивает сессию у Дiя API (api2s.diia.gov.ua)
  2. Получает deep link → конвертирует в QR-код
  3. Пользователь сканирует QR приложением Дiя на телефоне
  4. Далее — тот же поток: подтверждение → callback → JWT

Криптография: почему ECDSA

API Дiя требует хеширования requestId через ECDSA с SHA256. Не HMAC, не RSA — именно ECDSA. Это стандарт электронной подписи в Украине (ДСТУ 4145), и Дiя следует ему.

requestId = base64(ECDSA_SHA256(branchId + offerId + requestId))

Каждый запрос уникален. Каждая подпись верифицирована. Replay-атаки невозможны.

Что получаем от Дiя

После успешной авторизации:

Поле Описание
ФИО Фамилия, имя, отчество
Дата рождения Из документа
ИНН Индивидуальный налоговый номер
Серия/номер документа Паспорт или ID-карта
Фото Из документа (опционально)

Этого достаточно для полной идентификации на юридической платформе — и для будущей интеграции с ЕРАУ (верификация адвоката по ИНН).

Безопасность

UX: один тап вместо формы

На мобильном:

На десктопе:

Никаких паролей. Никаких форм регистрации. Никаких «подтвердите email». То же приложение, которым вы показываете права на блокпосте — теперь ваш ключ к юридическому AI.

Три метода авторизации

LEX AI теперь поддерживает три независимых метода входа:

Метод Уровень доверия Лучше всего для
Google OAuth Базовый Быстрый старт, ознакомление
Authentik SSO Корпоративный Юридические фирмы, организации
Дiя Государственный Полная идентификация, адвокаты

Юрист выбирает свой уровень. Платформа адаптируется.


Production post-mortem: Redis + nginx

После деплоя на продакшн за AWS Application Load Balancer авторизация через Дiю перестала работать. Полностью. Пользователи нажимали «Войти через Дiю» — и получали ошибку.

Причин оказалось две, и обе — инфраструктурные.

Первая: расхождение ключей в Redis. При инициации сессии Дiя мы записывали стейт с одним префиксом, а при обратном вызове читали с другим. Redis молча возвращал null, бэкенд считал сессию невалидной и отклонял callback. Фикс — унификация префиксов ключей в одном месте.

Вторая: nginx перезаписывал X-Forwarded-Proto. ALB корректно передавал https, но nginx в своей конфигурации принудительно ставил http. Callback URL формировался с HTTP-схемой, Дiя отклоняла его как несоответствующий зарегистрированному redirect URI. Решение — nginx теперь пропускает оригинальный заголовок от балансера, а не подставляет свой.

Обе проблемы не воспроизводились локально, потому что в dev-среде нет ALB и Redis-префиксы совпадали случайно. Это напоминание: staging должен максимально повторять продакшн.