← Блог

Keel: как спроектировать систему, в которой нельзя подсмотреть

В большинстве CRM «скрыть поле» означает убрать его с экрана. Данные при этом лежат в той же таблице, приходят в браузер в ответе API и достаются любому, кто откроет инструменты разработчика. Для обычной задачи этого достаточно. Для Keel — нет, потому что вся суть продукта в том, что часть людей не должна знать некоторых вещей. Объясню, как такое проектируется.

Задача: цепочка клиент → менеджер → декларант

Keel — веб-CRM для процесса ВЭД (внешнеэкономической деятельности). В процессе три роли:

  • Клиент — компания, которой нужно оформить груз.
  • Менеджер — работает с клиентом и знает его.
  • Таможенный декларант — оформляет документы и знает заявку.

Ключевое требование — обезличивание: менеджер никогда не знает, какой декларант ведёт заявку, а декларант никогда не знает, кто клиент. Это защищает коммерческую модель сервиса и персональные данные: нельзя «обойти» посредника, потому что нечего обходить.

Почему скрыть поле в интерфейсе — не решение

Если ограничение реализовано в интерфейсе, оно держится ровно до первого запроса к API. Типичные дыры:

  1. API возвращает объект целиком, а фронтенд просто не показывает часть полей.
  2. Сообщения об ошибках случайно раскрывают идентификаторы.
  3. Поиск, фильтры и сортировка позволяют вычислить скрытое значение косвенно.
  4. Экспорт и отчёты строятся запросом, который не знает про правила видимости.

Каждая такая дыра — реальный инцидент в продакшне. Поэтому в Keel ограничение лежит там, где обойти его нельзя.

Что сделано в архитектуре

Обезличивание обеспечивают сервер и физически раздельные базы данных:

УровеньКак работает
ХранениеДанные, которые разные роли не должны знать друг о друге, лежат в физически раздельных базах
СерверКаждый запрос выполняется в контексте роли. Сервер физически не обращается к тем данным, которые роли знать нельзя
APIРоль не получает лишних полей даже при ручном вызове. Отдаётся только то, что разрешено
ИнтерфейсПросто отображает то, что разрешил сервер. На него безопасность не опирается

Принцип такой: безопасность не должна зависеть от того, что разработчик не забыл добавить проверку. Если данных нет в ответе, их нельзя ни украсть, ни показать по ошибке.

Стек и почему он такой

  • Rust (axum, sqlx) — строгая типизация позволяет выражать правила доступа на уровне типов, и часть ошибок такого рода ловится компилятором, а не в продакшне. Библиотека sqlx умеет сверять SQL-запросы со схемой базы на этапе сборки.
  • Postgres — надёжная реляционная база с богатыми возможностями разграничения доступа.
  • S3 — хранилище документов.
  • Vue 3 + TypeScript — интерфейс с типизированным обращением к API.
  • Self-hosted, single-tenant — у каждого заказчика своя установка и свои данные, без общей мультиарендной базы.

Что ещё умеет продукт

Ядро CRM: роли, карточки клиентов с контролируемым доступом к персональным данным, заявки со SLA. Поверх него — управление задачами с канбан-досками, планирование по диаграмме Ганта, учёт времени, блочный редактор документов с экспортом в DOCX и PDF, а также каналы связи с клиентами через Telegram, email и WhatsApp.

Чему этот проект учит

  1. Требования безопасности нужно выявлять до проектирования, а не после. «Менеджер не должен знать декларанта» — это не пункт чек-листа в конце, это исходное условие, которое определило структуру баз данных.
  2. Безопасность — свойство архитектуры. Её нельзя «прикрутить» перед релизом. Подробнее о подходе: Безопасная разработка ПО: как защита закладывается с первого дня.
  3. Строгие инструменты экономят время. Типы и проверки при сборке ловят ошибки задолго до продакшна, а это часть Качество кода: что оно значит для бизнеса и как его обеспечить.
  4. Юридическая грамотность помогает. Персональные данные, роли и ответственность сторон нужно понимать до написания кода.

Нужна система с жёсткими правилами доступа?

Если в вашем продукте есть данные, которые разные группы людей не должны видеть, начните с проектирования границ доступа. Опишите задачу мне в Telegram: @w1shmaster. Как мы пройдём путь от идеи до работающей системы, расскажет статья Разработка ПО с нуля под ключ: от идеи до релиза.

← Все посты