Что продукт собирает, где хранит и сколько держит — инвентарь, умолчания сбора, сроки
хранения и что уходит за периметр — вынесено на отдельную страницу:
Безопасность и обработка данных. Этот чек-лист — про решения,
которые принимаете вы; та страница — про факты, на которых вы их принимаете.
Issuer и сертификаты
- Стабильный HTTPS issuer, актуальный JWKS, спланированная замена ключей.
iss токенов и в discovery.
Клиенты обязаны доверять ключам через discovery / JWKS, а не через зашитую статику: тогда
замена ключа не требует правок на их стороне. Вне Development сертификаты подписи и шифрования
обязательны в обоих режимах поставки, встроенном и self-hosted, — без них хост не стартует
(ключи: справочник конфигурации).
Клиентские секреты и хранение
-
client_secretи токены каналов — вне репозитория, через окружение, с шифрованием и ротацией.
client_secret, токены ботов, ключи API каналов) передаются только через
переменные окружения / секрет-стор, не через файлы конфигурации и не в гите. Шифруйте at-rest и
ротируйте.
OIDC PKCE и state
- PKCE (
S256) обязателен для public-клиентов; валидируйтеstateиnonce.
S256 обязателен. state защищает от CSRF на
редиректе, nonce привязывает id_token к сессии. Veriqa дополнительно проверяет одноразовый
browser-nonce в callback — не отключайте эти проверки.
Redirect URIs
- Whitelist exact-match; без wildcard в проде;
httpsтолько (кроме loopback в dev).
http допустим
только для loopback-адресов (localhost, 127.0.0.1, [::1]) при разработке.
Scopes и claims
- Минимальный набор scopes;
openidобязателен; не запрашивать лишний PII.
openid обязателен, остальное — по необходимости. Не просите email,
если он не нужен; не храните PII сверх требуемого. /userinfo отдаёт только claims,
разрешённые scopes и конфигурацией.
Rate limiting и anti-abuse
- Лимиты ядра подобраны под трафик каждого маршрута; per-IP-ограничитель стоит на reverse-proxy / WAF.
authorize,
token, callback, polling, вебхуки, SignalR, стартовая страница Email, страницы подтверждения
(дефолты — в конфигурации). Поверх этого оно считает
попытки входа по пользователю (channel identity), чтобы подтверждение нельзя было перебрать, и
даёт каждому relying party собственный бюджет на server-to-server входе подтверждения. Общие
бакеты подбирайте под суммарный трафик маршрута: они защищают доступность, а не одного посетителя
от другого.
Чего ядро не делает — не считает ни один лимит по IP клиента и не блокирует адреса.
Per-IP-лимит ловит единственное, чего не видят два других ключа, — горизонтальный перебор: много
аккаунтов с одного адреса, каждый в пределах своего пользовательского лимита, — и этот слой живёт на
краю, который у вас уже есть: limit_req в NGINX, rate-правило WAF, fail2ban по 429 в access-логе.
Тем же шагом развёртывания настраивается ForwardedHeaders:KnownProxies (см.
self-hosted, шаг 6): край видит реальный
адрес клиента, ядро доверяет только тому, что край пробросил. Установка без ограничителя на краю
открыта для такого перебора, поэтому поставьте его до выхода в прод.
Ротация refresh-токенов
- Включить rotation и revocation; реагировать на повторное использование.
Логирование и аудит
- Никогда не логировать токены / секреты / PII; включить аудит транзакций.
action), объект и исход (result).
Два известных ограничения журнала — учтите их, планируя отчётность и разбор инцидентов.Выпуск токенов не аудируется. Ни первичный выпуск по authorization code, ни ротация
refresh-токена аудит-записи не создают: журнал пишется по событиям транзакции, а выпуск
токенов через них не проходит и к транзакции не привязан — тем более ротация, которая
случается уже вне её жизненного цикла. Не стройте доказательство выдачи токена на
аудит-журнале: выпуск и ротацию контролируют отзыв токена и отзыв всего семейства при
replay (см. Ротация refresh-токенов).Исход канальной security-записи неинформативен. У записей, порождённых
security-событиями канала, поле исхода одинаково — «отказ», и так для любого кода канала.
«Отказ» в такой строке не значит «что-то сломалось»: смысл события несёт код в поле
action, а его словарь даёт документация конкретного канала. Фильтруйте и разбирайте
такие записи по action, а не по исходу.Program.cs
Уровень проверки входящего события канала
-
InboundVerificationобъявлен у каждой канальной секции — и объявлен осознанно.
InboundVerification: развёртывание с включённым
поставляемым каналом без значения не стартует. Стартовая проверка перебирает тот же
набор каналов, из которого ядро строит список включённых: все четыре поставляемых канала в нём есть,
а канал стороннего адаптера, подключённый одним вызовом AddChannel, — нет, и его секцию
проверяете глазами вы. Смотрите не на то, что ключ есть, а на то, что в нём написано: значение
обязано соответствовать режиму, в котором канал реально работает (таблица — в
Настройке каналов). Расхождение здесь тихое: канал в вебхук-режиме, которому
объявили outbound_fetch, стартует молча.
none — осознанный выбор, а не умолчание: он означает «подлинность входящего события не
проверяется», то есть эндпоинт подтверждения этого канала принимает запрос от кого угодно.
Ставьте его, только если действительно приняли этот риск, и заносите такое решение туда, где
хранятся остальные решения о рисках.
Доступность каналов
- Определить поведение при недоступности канала.
Локализация и доступность
- WCAG 2.2 AA; locale-файлы для языков вашей аудитории.
Dockerfile
поставляет переводы на английский, русский и китайский; во встроенном режиме каталог локалей
поставляет ваш хост, и без него страница отображается на английском (см.
Локализацию). Формального аудита доступности с
публикуемым отчётом не проводилось — если он требуется вашему регламенту, планируйте его на своей
стороне.
Версионирование и миграции
- SemVer SDK; для реляционных хранилищ — миграции, а не авто-создание схемы.
Операционные основы
- Health-probe, шифрованный канал к БД, secret storage, внешний JS на странице входа выключен.
Дальше
OIDC + Veriqa: разбор
Разберитесь, где именно Veriqa встаёт в OIDC-поток.