API-ключи
Три вида учётных данных, три модели угроз.
pk_ — Publishable
- Предназначен для отправки в браузер. Передаётся как заголовок
X-Client-IDна каждом подписанном B2B-запросе, также встроен в бандл SDK для клиентских открытий checkout. - Может идентифицировать ваш аккаунт; не может создавать сессии, читать данные других мерчантов или запускать что-то деструктивное.
- Утечка publishable-ключа — низкая угроза.
sk_ — Secret (HMAC-ключ подписи)
- Ключ подписи HMAC-SHA256 для всех B2B API-вызовов — см. Аутентификация.
- Никогда не путешествует по сети. Только его подпись per-request. Поэтому беспокоиться о утечках нужно только на уровне хранения (env vars, git, логи), а не на транспортном уровне.
- Только серверный. Никогда не должен появляться в браузерном бандле, публичном репо, скриншоте или сообщении в чате.
- Утечка секрета — высокая угроза.
whsec_ — Секрет подписи webhook
- Используется для проверки подписи на входящих доставках webhook от нас к вашему серверу. См. Проверка подписи.
- Отдельный для каждого webhook-endpoint’а — если у вас 3
зарегистрированных endpoint’а, у вас 3 разных секрета
whsec_. Окружение закодировано в префиксе:whsec_live_…/whsec_test_…. - Только серверный. Как и
sk_, никогда не путешествует по сети — используется только для проверки HMAC локально. - У ротации есть 24-часовое grace-окно. Нажмите Rotate, и
предыдущий секрет остаётся принимаемым 24 часа наряду с новым
(доставки несут и
X-Signature, иX-Signature-Prev), чтобы вы могли переразвернуть verifier без удержания трафика. - Reveal-existing-secret доступен, защищён свежим 2FA и записывается в журнал аудита — для случая, когда секрет потерян и ротация неприемлема. Дефолтная позиция панели — «ротировать, не раскрывать».
- Утечка webhook-секрета позволяет атакующему подделывать события на ваш URL. Средне-высокая угроза в зависимости от того, насколько вы доверяете payload’у события.
Scope’ы
Secret-ключи scope’ятся. Панель позволяет выпускать ключи с одним из этих наборов scope’ов:
| Scope | Может делать | Используется для |
|---|---|---|
read | Чтение списков и единичных заказов, сессий, возвратов, балансов | Read-only интеграции (аналитика, BI) |
write_order | Всё read + создание сессий, создание заказов, отмена заказов | Backend витрины |
write_refund | Всё read + создание возвратов, пометка возвратов исполненными | Инструменты поддержки клиентов |
webhook_manage | Всё read + управление webhook-endpoint’ами | DevOps-тулинг |
Ключ default-mint «full access» получает все четыре. Выпуск per-purpose ключей всё равно хорошая гигиена — это документирует намерение и готовит вас к применению, когда оно появится — но прочтите оговорку ниже, прежде чем рассматривать scope как границу безопасности.
Scope’ы сегодня рекомендательные — они не применяются на gateway.
Gateway проверяет HMAC-подпись ключа и инжектирует вашу идентичность
мерчанта (X-Merchant-ID / X-Merchant-Domain) в downstream-сервисы,
но не пропагирует и не проверяет scope ключа. На практике это
значит, что утёкший sk_ любого scope’а может вызвать любой
endpoint /b2b/v1/* для вашего мерчанта — ключу read фактически не
запрещено создавать возврат. Поэтому узкие scope’ы пока не
ограничивают радиус взрыва: для планирования инцидентов считайте
каждый secret-ключ ключом с полным доступом и полагайтесь на быструю
ротацию + отзыв (ниже) как на реальное сдерживание. Применение
per-scope в roadmap.
Ротация
- Сгенерируйте новый ключ. Панель → Developers → API keys → + Add key. Выберите scope. Панель отображает секрет один раз — сохраните его сразу.
- Прокатите env vars на новое значение во всех окружениях. Разверните.
- Проверьте трафик. Панель показывает счётчики запросов per-ключ в реальном времени. Подождите, пока счётчик старого ключа упадёт до нуля.
- Отзовите старый ключ. Тот же экран → меню kebab → Revoke.
Сегодня нет автоматического окна перекрытия — как только вы
отзываете ключ, любой in-flight запрос, подписанный им, получает
401. Планируйте ротацию соответственно: разверните новый ключ
первым, дренируйте трафик со старого, затем отзывайте.
Экстренный отзыв
Если ключ утёк (в истории git, в публичном бандле, в логированном стек-трейсе, в pen-test отчёте партнёра) — отзовите его немедленно, даже ценой нескольких упавших запросов. Лучше упасть громко, чем позволить атакующему держать валидный credential.
Шаги:
- Панель → Developers → API keys → [ключ] → Revoke now. Эффект мгновенный; grace-периода нет.
- Выпустите замену и разверните.
- Проверьте недавнюю активность — панель показывает последние 30 дней запросов per-ключ с IP и затронутыми endpoint’ами.
Если вы подозреваете, что брешь шире одного ключа, обратитесь к [email protected], чтобы:
- Получить полный экспорт журнала аудита для вашего мерчантского аккаунта
- Ротировать webhook-секреты массово
- Опционально заморозить аккаунт на время расследования
Лучшие практики хранения
- Только env vars. Никогда не коммитьте секреты в git, даже в
.env.exampleсо словами «REPLACE ME». - Per-environment ключи. Разные
sk_test_…иsk_live_…для dev/staging/prod, источники из вашего secrets manager’а (AWS Secrets Manager, Vault, Doppler, …). - Ограничьте доступ к env vars. В Kubernetes монтируйте как
Secret, неConfigMap. В Vercel/Netlify используйте scope environment-переменных, а не project-wide global’ы. - Не логируйте запросы с телами. Даже при отладке — ваша
HMAC-подпись в
X-Signatureодноразовая, но ваш бизнес-payload может содержать PII.
Что НЕ поддерживается сегодня
- IP-allowlisting для secret-ключей. В roadmap.
- OAuth-стиль scope’ируемые per-user токены. Текущая модель ключей per-merchant, не per-user.
- Автоматическая ротация ключей (например, еженедельная принудительная ротация платформой). Вручную сегодня.
Что дальше
- Аутентификация — точный алгоритм подписи для B2B-вызовов.
- Webhooks → Проверка подписи
— как
whsec_используется на входящих событиях.