Модель безопасности токенов
Токены L402 состоят из двух частей, соединённых символом::
- Macaroon — JSON в кодировке base64, содержащий
{hash, exp}. Подписан с помощью SHA-256. Невозможно подделать без знания preimage. - Preimage — 32-байтовый секрет, хэш которого через SHA-256 должен совпадать с хэшем, встроенным в macaroon.
Защита от повторного использования
l402-kit включает встроенную защиту от повторного использования. Каждый preimage может быть использован только один раз:401 Token already used.
Хранилище по умолчанию: Set в памяти. Это означает:
- Перезапуски очищают хранилище (токены становятся повторно используемыми после перезапуска)
- Несколько экземпляров не разделяют состояние
Срок действия токенов
Токены содержат полеexp (Unix-временная метка в мс). SDK автоматически отклоняет просроченные токены.
TTL по умолчанию: 1 час (устанавливается провайдером Lightning при создании инвойса).
HTTPS обязателен
Никогда не используйте L402 через обычный HTTP в продакшене. Macaroon и preimage передаются в заголовкеAuthorization. По HTTP они доступны сетевым злоумышленникам.
Ограничение частоты запросов
L402 проверяет токены криптографически, без обращения к базе данных — это дёшево. Но создание Lightning-инвойса (ответ 402) обращается к API вашего Lightning-провайдера. Защитите создание инвойсов с помощью ограничителя частоты запросов для предотвращения DoS:Управление секретами
Никогда не вшивайте API-ключи в код. Используйте переменные окружения:.env + dotenv (никогда не коммитьте в git).
Аутентификация административных эндпоинтов
Если вы открываете административные или статистические эндпоинты, никогда не принимайте секреты через URL-параметры. URL-адреса полностью логируются обратными прокси, CDN и облачными провайдерами — включая строку запроса.Гигиена ключей Supabase
ИспользуйтеSUPABASE_SERVICE_KEY (только на сервере) и SUPABASE_ANON_KEY (безопасно передавать клиентам) правильно:
| Ключ | Использование | Обходит RLS? |
|---|---|---|
anon | Расширение VS Code, браузерные клиенты | Нет |
service_role | Серверные функции API | Да |
pro_access), должны использовать сервисный ключ — никогда не anon-ключ. Политики RLS на чувствительных таблицах не должны предоставлять доступ anon.
Политика безопасности контента
Если вы обслуживаете фронтенд вместе с API, убедитесь, что ваш CSP не блокирует поток L402:Управление данными — удаление пользовательских данных
Пользователи могут удалить всю историю платежей и Pro-подписку из расширения VS Code в любое время (Настройки → Опасная зона). Расширение вызывает:- Всех строк в
payments, гдеowner_address = ? - Всех строк в
pro_access, гдеaddress = ?
Расширение требует, чтобы пользователь точно ввёл свой Lightning-адрес перед активацией кнопки удаления — подтверждение в стиле GitHub для деструктивных действий.
Конфиденциальность и минимизация данных
l402-kit разработан для сбора минимального количества данных, необходимых для работы. Ниже описано, что хранится, зачем и как защитить каждое поле.Что хранится
| Таблица | Поле | Зачем | Чувствительность |
|---|---|---|---|
payments | preimage | Защита от повторного использования + доказательство оплаты | ⚠️ Средняя — лучше хэшировать (см. ниже) |
payments | owner_address | Атрибуция дохода Lightning-адресу | Низкая — Lightning-адреса публичны |
payments | amount_sats | Статистика дашборда | Низкая |
payments | endpoint | Аналитика по эндпоинтам | Низкая–средняя |
pro_access | address | Проверка Pro-подписки | Низкая — публичный |
waitlist | email | Отправка приветственных писем и писем о релизе | ⚠️ Высокая — настоящие персональные данные, шифруйте или не храните |
waitlist | lightning_address | Опциональный идентификатор | Низкая |
Храните хэши preimage вместо сырых значений
Preimage — это 32-байтовый секрет, доказывающий, что Lightning-платёж был совершён. Хранение в сыром виде означает, что при утечке базы данных раскрываются все доказательства. Храните хэш SHA-256 — он уже публичен (встроен в BOLT11-инвойс) и достаточен для защиты от повторного использования:Защита email-адресов списка ожидания
Email-адреса — единственные настоящие персональные данные в системе. Варианты в порядке возрастания защиты:Подтверждение владения кошельком перед удалением данных (LNURL-auth)
Эндпоинт/api/delete-data должен принимать запросы только от реального владельца Lightning-адреса. Используйте LNURL-auth для криптографического подтверждения владения — пользователь подписывает серверный вызов приватным ключом своего Lightning-кошелька, без пароля и аккаунта:
См. полную диаграмму потока для полной последовательности с состоянием Supabase.
Это гарантирует, что никто не сможет удалить записи другого пользователя, даже зная Lightning-адрес.
Чек-лист
Перед запуском в продакшен
Перед запуском в продакшен
- HTTPS принудительно включён на всех эндпоинтах
- API-ключи в переменных окружения, не в исходном коде
- Административные/статистические эндпоинты используют аутентификацию через заголовок, не параметры URL
?secret= - Ключ
service_roleSupabase используется на стороне сервера; ключanonтолько на клиентах - Чувствительные таблицы Supabase не имеют политики SELECT для
anon - Эндпоинт удаления данных (
/api/delete-data) использует сервисный ключ, никогда не anon - Ограничитель частоты запросов на создание инвойсов
- Защита от повторного использования протестирована (попробуйте повторно использовать preimage → ожидается 401)
- Истечение срока токена протестировано (установите короткий TTL в разработке, подтвердите 401 после истечения)
- Preimage хранятся как хэши SHA-256, не сырые секреты
- Email-адреса списка ожидания зашифрованы в покое или удалены после отправки
-
/api/delete-dataтребует подтверждения владения кошельком через LNURL-auth
Для высоконагруженных API
Для высоконагруженных API
- Хранилище защиты от повторного использования на основе Redis (общее для всех экземпляров)
- Мониторинг частоты ответов 402 (всплеск = потенциальный DoS)
- Резервный Lightning-провайдер (BlinkProvider → резервный LNbitsProvider)
- Мониторинг страницы статуса вашего Lightning-провайдера (например, status.blink.sv)