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

AUTH-POLICIES — Руководство по политикам аутентификации

Таблица pm.auth_policies реализует policy-based step-up authentication: решение о нужном уровне авторизации принимается динамически на основе контекста транзакции (сумма, новый получатель, накопленный дневной объём), а не хардкодится в логике интента.


Справочник полей

Поле Тип Обязательное Описание
id BIGSERIAL авто Первичный ключ, генерируется автоматически
scope VARCHAR(80) Область применения (см. ниже)
condition JSONB Условия срабатывания (см. ниже)
required_step_up VARCHAR(20) Требуемый уровень аутентификации
reason_code VARCHAR(50) Код причины, возвращается в ответе API
priority INTEGER ✅ (default 100) Порядок проверки: меньше = первее
active BOOLEAN ✅ (default true) Включено/выключено без удаления строки
created_at TIMESTAMPTZ авто Дата создания
updated_at TIMESTAMPTZ авто Дата последнего обновления

Поле scope — область применения

global                 — применяется ко всем платежам
app:{appId}            — только платежи из конкретного mini-app
merchant:{merchantId}  — только платежи конкретному мерчанту

При оценке движок загружает все три скоупа сразу и сортирует по priority. Можно создавать правила с одинаковым приоритетом в разных скоупах — они конкурируют между собой.


Поле required_step_up — уровни аутентификации

Значение Смысл
NONE Подтверждение не требуется
PIN Ввод PIN-кода
OTP Одноразовый код (SMS/email)
BIOMETRIC Биометрия (Face ID / Touch ID)
KYC_UPLIFT Повышение уровня KYC пользователя

Поле condition — поддерживаемые ключи JSONB

Все ключи соединяются AND — все указанные условия должны выполняться одновременно.

Ключ Тип значения Описание
amount_lt number Сумма строго меньше указанного значения
amount_gte number Сумма больше или равно указанному значению
amount_lte number Сумма меньше или равно указанному значению
daily_cumulative_gte number Дневной оборот пользователя (settled DEBIT) ≥ значения
new_payee boolean true — мерчант ранее не получал платежи от этого пользователя
currency string Фиксирует валюту, например "THB"
channel string Канал платежа: INTERNAL_P2P, IPPS_TRANSFER, MERCHANT_INVOICE

Важно: суммы хранятся в наименьших единицах валюты. Для THB: 1 бат = 100 сатангов → 100 бат = 10000, 5 000 бат = 500000, 50 000 бат = 5000000.


Поле priority — логика приоритетов

Движок берёт первое совпавшее правило и останавливается. Если нужно, чтобы строгое правило перекрывало мягкое — дай ему меньший номер.

priority 1   ← проверяется первым, наивысший приоритет
priority 5
priority 10
...
priority 100 ← default, самый низкий приоритет

Создание правил — примеры SQL

Микроплатежи не требуют подтверждения

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES ('global', '{"amount_lt": 10000}', 'NONE', 'micro_amount', 10);

PIN для новых получателей с суммой ≥ 100 бат

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES ('global', '{"new_payee": true, "amount_gte": 10000}', 'PIN', 'new_payee', 15);

Биометрия для крупных сумм (≥ 5 000 бат)

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES ('global', '{"amount_gte": 500000}', 'BIOMETRIC', 'large_amount', 30);

KYC при превышении дневного лимита (50 000 бат)

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES ('global', '{"daily_cumulative_gte": 5000000}', 'KYC_UPLIFT', 'daily_limit', 5);

Особое правило только для одного mini-app

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES ('app:my-app-id', '{"amount_gte": 50000}', 'PIN', 'app_threshold', 25);

Строгое правило для конкретного мерчанта

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES ('merchant:42', '{"amount_gte": 100000}', 'BIOMETRIC', 'merchant_strict', 5);

PIN только для платежей через IPPS (не для внутренних P2P)

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES ('global', '{"channel": "IPPS_TRANSFER", "amount_gte": 10000}', 'PIN', 'ipps_standard', 20);

Комбинированное условие: новый получатель + крупная сумма + валюта

INSERT INTO pm.auth_policies (scope, condition, required_step_up, reason_code, priority)
VALUES (
  'global',
  '{"new_payee": true, "amount_gte": 100000, "currency": "THB"}',
  'BIOMETRIC',
  'new_payee_large_thb',
  8
);

Редактирование правил

Отключить правило (без удаления)

UPDATE pm.auth_policies SET active = false, updated_at = now() WHERE id = 3;

Включить обратно

UPDATE pm.auth_policies SET active = true, updated_at = now() WHERE id = 3;

Изменить порог суммы в condition

UPDATE pm.auth_policies
SET condition = '{"amount_gte": 200000}', updated_at = now()
WHERE id = 4;

Изменить требуемый уровень аутентификации

UPDATE pm.auth_policies
SET required_step_up = 'OTP', updated_at = now()
WHERE id = 2;

Изменить приоритет

UPDATE pm.auth_policies
SET priority = 12, updated_at = now()
WHERE id = 5;

Удалить правило

DELETE FROM pm.auth_policies WHERE id = 5;

Типичные ошибки

Перекрывающиеся диапазоны без учёта приоритета:

Политика A (priority 20): {"amount_gte": 10000, "amount_lt": 500000} → PIN
Политика B (priority 10): {"amount_gte": 50000}                      → BIOMETRIC
Платёж 100 000 → сработает B (priority 10), несмотря на то что A тоже подходит.

Пустой condition: {} — сработает на любой платёж. Если такое нужно (catch-all), ставь максимальный priority (например, 999).

new_payee без merchantId в запросе — если вызывающий не передаёт merchantId, флаг isNewPayee всегда будет false, и правило с new_payee: true никогда не сработает.


Немедленное применение изменений

Изменения вступают в силу немедленно — движок читает таблицу при каждом вызове POST /policies/evaluate, кэширования нет. Это удобно для оперативной реакции на фрод, но означает что ошибочное правило с priority: 1 и condition: {} мгновенно потребует step-up от всех пользователей.


Связанные файлы

Файл Описание
src/limits/evaluate-policy.ts Логика оценки политик
src/policies/routes.ts HTTP endpoint POST /policies/evaluate
src/shared/schema.ts Drizzle-схема таблицы и типы
drizzle/migrations/0008_auth_policies.sql Миграция + базовые seed-данные
test/limits/evaluate-policy.test.ts Unit-тесты логики
test/policies/routes.test.ts Интеграционные тесты endpoint