Это руководство описывает аутентификацию в Vilna API, верификацию подписей вебхуков и защиту учётных данных.
Каждый запрос к Vilna API должен содержать API-ключ в заголовке X-Api-Key.
Доступ к API предоставляется на уровне рабочего пространства. Для начала работы:
- Запросите доступ на support@vilna.io.
- Вы получите пространство имён (namespace) и API-ключ.
- Ваш базовый URL:
https://{namespace}.vilna.app.
curl "https://${VILNA_NAMESPACE}.vilna.app/blockchains" \
-H "X-Api-Key: your-api-key"Если ключ отсутствует или недействителен, API возвращает ошибку в формате RFC 7807:
{
"type": "https://docs.vilna.io/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid or missing API key."
}Каждое рабочее пространство работает в собственном пространстве имён. Пространство имён определяет базовый URL вашего API и изолирует данные от других организаций.
https://{namespace}.vilna.appВсе адреса, балансы, каналы уведомлений и другие ресурсы привязаны к вашему пространству имён. Вы не можете получить доступ к ресурсам другого пространства имён.
Vilna использует три типа API-ключей, каждый из которых предназначен для определённого сервиса и области действия.
| Тип | Префикс | Область действия | Назначение |
|---|---|---|---|
| API-ключ | vilna_api_ | Проект | Доступ к Platform API (адреса, транзакции, балансы) |
| RPC-ключ | vilna_rpc_ | Рабочее пространство | Доступ к блокчейн-нодам через Vilna RPC |
| Управляющий ключ | vilna_mgt_ | Рабочее пространство | Management API (пространства, проекты, участники, ключи) |
API-ключи привязаны к проекту. Каждый ключ связан с конкретным проектом в рабочем пространстве и может обращаться только к ресурсам этого проекта. Если у вас несколько проектов, для каждого нужен отдельный API-ключ.
RPC-ключи и управляющие ключи действуют на уровне рабочего пространства. Они работают со всеми проектами в пространстве. RPC-ключ предоставляет доступ к эндпоинтам блокчейн-нод, а управляющий ключ позволяет программно управлять пространствами, проектами, участниками и другими ключами.
Каждый тип ключа имеет собственный набор разрешений, определяющих доступные операции. Например, API-ключ может иметь разрешение api:address:read, но не api:address:write. Полная матрица разрешений доступна в справочнике по авторизации.
Все три типа ключей передаются в одном заголовке X-Api-Key. Шлюз определяет тип ключа по префиксу и автоматически направляет запрос в нужный сервис.
Длина ключа составляет 40 символов: префикс типа, 24 случайных символа base62 и 6 контрольных символов CRC32. Например:
vilna_api_aBcDeFgHiJkLmNoPqRsTuVwX123456Создавать и управлять ключами можно через Management API или панель управления Vilna.
Верификация подписей вебхуков пока недоступна. В настоящее время API доставляет вебхуки без криптографических подписей. Эта функция запланирована в одном из ближайших обновлений.
Когда Vilna доставляет вебхук-событие, запрос включает заголовки для проверки подлинности и предотвращения атак воспроизведения.
| Заголовок | Описание |
|---|---|
X-Webhook-Signature | HMAC-SHA256 подпись тела запроса |
X-Webhook-Event | Тип события (transaction_alert или test) |
X-Webhook-Idempotency-Key | Уникальный идентификатор доставки для дедупликации |
X-Webhook-Timestamp | Unix-временная метка отправки события |
Сформируйте подписываемый payload, соединив временную метку, точку (.) и тело запроса. Вычислите HMAC-SHA256 дайджест, используя секрет вебхука в качестве ключа, затем сравните его со значением в X-Webhook-Signature.
При создании канала уведомлений ответ API содержит поле secret. Это ваш секрет для подписи вебхуков — сохраните его в надёжном месте. Используйте его для проверки того, что входящие вебхук-запросы действительно отправлены Vilna. Секрет уникален для каждого канала и отображается только один раз при создании.
Секрет вебхука уникален для каждого канала уведомлений и отображается только при создании. Сохраните его в менеджере секретов немедленно.
import crypto from "node:crypto";
function verifyWebhookSignature(
body: string,
signature: string,
timestamp: string,
secret: string
): boolean {
const payload = `${timestamp}.${body}`;
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Всегда используйте сравнение с постоянным временем (timingSafeEqual) для защиты от атак по времени. Включение временной метки в подпись предотвращает атаки воспроизведения: любое изменение метки делает подпись недействительной.
Сравните заголовок X-Webhook-Timestamp с текущим временем. Отклоняйте события старше допустимого окна (например, 5 минут):
const MAX_AGE_SECONDS = 300; // 5 минут
function isTimestampValid(timestamp: string): boolean {
const eventTime = parseInt(timestamp, 10);
const now = Math.floor(Date.now() / 1000);
return Math.abs(now - eventTime) <= MAX_AGE_SECONDS;
}Используйте заголовок X-Webhook-Idempotency-Key для обнаружения и пропуска дублирующихся доставок. Сохраняйте обработанные ключи в кэше или базе данных и отклоняйте любой ключ, который вы уже обрабатывали.
Никогда не раскрывайте ключи во фронтенд-коде. API-ключи предоставляют полный доступ к вашему пространству имён. Храните их только на серверной стороне.
Используйте переменные окружения. Храните учётные данные в переменных окружения или менеджере секретов, а не в исходном коде.
export VILNA_API_KEY="your-api-key"const client = createVilnaClient({
namespace: process.env.VILNA_NAMESPACE!,
apiKey: process.env.VILNA_API_KEY!,
});Регулярно ротируйте ключи. Если ключ скомпрометирован, свяжитесь с support@vilna.io для его отзыва и выпуска нового.
Используйте отдельные ключи для каждого окружения. Используйте разные API-ключи для разработки, стейджинга и продакшна, чтобы утечка в одном окружении не затронула остальные.
Ограничивайте сетевой доступ. По возможности добавьте в белый список IP-адреса, с которых ваш сервер обращается к Vilna API.
Все ошибки аутентификации и авторизации соответствуют формату RFC 7807 application/problem+json:
| Статус | Значение |
|---|---|
401 | Отсутствующий или недействительный API-ключ |
403 | Действительный ключ, но недостаточно прав |
{
"type": "https://docs.vilna.io/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Your API key does not have access to this resource."
}Полная информация об обработке ошибок доступна в Platform API.