Что защищает арендатора, сказано прямо.
Никаких сертификаций, которых у нас нет, и никаких прилагательных вместо средств контроля. Вот что обеспечивается, где обеспечивается и чего не хватает.
Изоляция структурна, а не поднадзорна.
Каждый запрос к данным рабочего пространства несёт его id в условии. Не существует пути доступа без области видимости, который можно было бы забыть применить.
Этот дизайн убирает самый обыкновенный отказ: корректная система, в которой один новый эндпойнт, написанный в спешке, теряет условие WHERE. Если слой данных не отвечает на вопрос, в котором не назван рабочий пространство, такой эндпойнт не компилируется в утечку — он вообще не компилируется.
Состязательные тесты на утечку закрепляют это свойство, вместо того чтобы полагаться на договорённость: договорённость хороша ровно настолько, насколько внимателен был последний, кто читал файл.
internal/tenancy · migrations/0002
Журнал аудита защищён от изменений в базе данных, а не в приложении.
Триггер выбрасывает ошибку при любом обновлении или удалении. Приложение, решившее не переписывать историю, — это политика; база данных, отказывающаяся её переписывать, — это средство контроля.
Именно об этой разнице спрашивает аудитор, и именно на неё поставщик обычно не может ответить. Если единственное, что мешает задним числом что-то поправить, — это отсутствие такого пути в коде, то скрипт поддержки, миграция или оператор с консолью всё равно смогут это сделать, а журнал об этом не узнает.
internal/tenancy · migrations/0002 audit_log_immutable()
Ключи ротируются без простоя. Вход устойчив к фишингу.
Ротация, которой нужно окно техработ, — это ротация, которая не происходит.
- 01
Идентификаторы ключей с пересекающимся сроком действия
Ключи API и ключи подписи вебхуков каждого рабочего пространства несут идентификатор ключа. Во время ротации действительны оба, поэтому вы переключаетесь по собственному графику и отзываете старый после.internal/tenancy · internal/outbox/sign.go
- 02
Passkey и для участников, и для операторов
WebAuthn с обязательной проверкой пользователя и обнаруживаемыми учётными данными — не по желанию, потому что эти ключи стоят прямо перед денежным потоком. Обнаруживаемый вход находит аккаунт по самим учётным данным, поэтому ничего не набирается и нечего выманивать.internal/passkey
- 03
Двухфакторка через приложение, хранится правильно
Секрет TOTP нельзя захешировать — проверка заново вычисляет из него коды, — поэтому секреты участников запечатываются AES-256-GCM под подключом, отдельным для этого назначения, а не лежат открытым текстом. Счётчик принятого кода записывается обратно, поэтому код нельзя переиспользовать внутри его окна.internal/membertotp · internal/secretbox
- 04
Хешируем, где можем; запечатываем, где нельзя
Пароль или код восстановления хешируются, потому что платформе достаточно ответить «это он?». Секрет, который платформе нужно прочитать обратно, вместо этого запечатывается, а хранилища, появившиеся раньше этой конструкции, переводятся на неё, а не оставляются как есть.internal/secretbox
Ничто не утекает через URL, который настроили вы.
Адрес назначения вебхука по своей природе — ввод, на который влияет атакующий: это URL, который набирает арендатор, а платформа затем обращается к нему изнутри собственной сети.
Диспетчер прогоняет проверку исходящего трафика до отправки запроса, а не доверяет имени хоста; помогает только такой порядок: проверка после разрешения имени или проверка строки вместо самого адреса — это ровно та проверка, которую перешагивает атака DNS rebinding. Loopback и адреса частных сетей разрешены только в песочнице и сквозных прогонах, и это послабление задаётся явным флагом, а не угадыванием окружения.
internal/outbox/ssrf.go · internal/outbox/dispatcher.go
Мы не кастодиан, и код отказывается им становиться.
Никаких средств участников. Никаких приватных ключей. Никаких данных платформы внутри платёжного канала арендатора.
Участники платят вам
internal/rails
Конфигурация отвергает наши
internal/rails
Выплата поручает, но не перемещает
internal/claims
Проверка без хранения документов.
Сессия провайдера идёт на вашем собственном аккаунте. Возвращается решение и необратимый идентификатор.
Этого идентификатора хватает, чтобы обеспечить «один человек — одна позиция», и не более того. Восстановить по нему личность нельзя, и в этом весь смысл: самый безопасный способ хранить скан паспорта — не хранить его, а утечка не может раскрыть данные, которых никогда не было.
internal/verification
Чего мы не заявляем.
Если вы заполняете опросник по поставщику, вот строки, по которым мы не пройдём. Лучше здесь, чем на четвёртый месяц.
See /contact#security
Пришлите опросник или возьмите песочницу и посмотрите сами.
И то и другое нормально. Один из вариантов быстрее.