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

Yandex Cloud Functions и n8n: безопасный webhook-прокси для событий

Обновлено: 2026-05-30

AI summary: Практический сценарий, где Cloud Functions принимает внешнее или облачное событие, подписывает payload, передает его в n8n, а workflow проверяет HMAC, дедуплицирует событие и запускает бизнес-автоматизацию без открытого публичного webhook без защиты.
Шаблон для внедрения

Импортируйте workflow, замените credentials и прогоните тестовый payload до включения production.

Проблема: Yandex Cloud Functions удобно использовать как serverless-точку входа, но если она просто прокидывает JSON в n8n, любой получивший URL сможет имитировать событие и запускать workflow.

Решение: сделать Cloud Functions тонким защищённым прокси: функция добавляет timestamp, event_id и HMAC-подпись, n8n проверяет подпись, отсеивает повторы и только потом отправляет событие в CRM, Telegram, S3 или внутренний API.

Схема безопасного webhook-прокси Yandex Cloud Functions для n8n
Cloud Function подписывает событие, n8n проверяет HMAC, event_id и маршрутизирует только валидный payload.

Проблема: почему публичный webhook n8n нельзя оставлять без защиты

Связка “Cloud Functions → n8n” часто нужна для событий Object Storage, Message Queue, API Gateway или небольших публичных интеграций. Проблема в том, что n8n webhook по умолчанию — это URL. Если он утечёт в логах, документации или фронтенде, злоумышленник сможет отправлять фальшивые события.

Без подписи нельзя отличить настоящее событие от ручного POST. Без idempotency повторная доставка может запустить бизнес-действие дважды. Без timestamp нельзя ограничить replay-атаки. Поэтому статья закрывает не “как дернуть n8n из функции”, а как сделать безопасный event ingress.

Архитектура связки Yandex Cloud Functions → n8n

НодаРольЧто проверить
Cloud Functionпринимает событие или HTTP-запросservice account, секрет, timeout
Sign payloadдобавляет `x-nodbot-signature`HMAC SHA-256, timestamp, event_id
n8n Webhookпринимает подписанное событиеproduction URL, только POST
Verify signatureсравнивает HMAC и возраст событияconstant-time compare, max age
Idempotency checkне пропускает повторный event_idPostgres unique key или durable storage
Route eventзапускает нужный бизнес-процесстип события, retry, alert

Cloud Functions не должна содержать бизнес-логику CRM. Её задача — принять событие, подписать его и быстро передать в n8n. Так проще менять automation-логику без redeploy функции.

Контракт события от Cloud Functions

{
  "event_id": "yc-evt-2026-05-30-00091",
  "event_type": "object_storage.created",
  "bucket": "client-docs",
  "object_key": "incoming/report-1042.pdf",
  "occurred_at": "2026-05-30T10:00:00Z",
  "metadata": {
    "tenant_id": "acme",
    "source": "yandex-cloud-functions"
  }
}

`event_id` должен быть стабильным для повторной доставки одного и того же события. Если источник не даёт такой ID, соберите его из bucket, object_key, version и timestamp источника.

Code Node: проверка HMAC, timestamp и event_id

const crypto = require('crypto');
const secret = $env.YC_N8N_WEBHOOK_SECRET;
if (!secret) throw new Error('YC_N8N_WEBHOOK_SECRET is not configured');

const headers = $json.headers ?? {};
const body = $json.body ?? $json;
const signature = String(headers['x-nodbot-signature'] ?? headers['X-Nodbot-Signature'] ?? '');
const timestamp = String(headers['x-nodbot-timestamp'] ?? headers['X-Nodbot-Timestamp'] ?? '');
const eventId = String(body.event_id ?? '').trim();

if (!eventId) throw new Error('Missing event_id');
if (!timestamp || Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) {
  throw new Error('Webhook timestamp is missing or too old');
}

const raw = JSON.stringify(body);
const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.${raw}`).digest('hex');
if (!signature || !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
  throw new Error('Invalid Cloud Functions signature');
}

return [{
  json: {
    event_id: eventId,
    idempotency_key: `yc-functions:${eventId}`,
    event_type: body.event_type,
    payload: body,
    verified_at: new Date().toISOString()
  }
}];
Что должна делать сама Cloud Function

Функция должна собрать raw JSON, timestamp в миллисекундах и подпись HMAC SHA-256 по строке timestamp.body. Секрет хранится в переменных окружения Cloud Functions и n8n, но не попадает в payload или лог ответа.

Готовый workflow JSON: скачать и импортировать

Скачать готовый workflow JSON Скачать тестовый payload

{
  "name": "Nodbot - Yandex Cloud Functions to n8n secure webhook",
  "nodes": [
    {
      "name": "n8n Webhook",
      "type": "n8n-nodes-base.webhook",
      "purpose": "Принять событие от Cloud Functions"
    },
    {
      "name": "Verify HMAC signature",
      "type": "n8n-nodes-base.code",
      "purpose": "Проверить подпись, timestamp и event_id"
    },
    {
      "name": "Check idempotency",
      "type": "n8n-nodes-base.postgres",
      "purpose": "Отсеять повторную доставку"
    },
    {
      "name": "Route by event type",
      "type": "n8n-nodes-base.code",
      "purpose": "Выбрать сценарий по event_type"
    },
    {
      "name": "Call business workflow",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Запустить CRM/S3/Telegram/API действие"
    },
    {
      "name": "Respond to Cloud Function",
      "type": "n8n-nodes-base.respondToWebhook",
      "purpose": "Вернуть безопасный статус"
    }
  ],
  "connections": "n8n Webhook → Verify HMAC signature → Check idempotency → Route by event type → Call business workflow → Respond to Cloud Function"
}

Пошаговая настройка Cloud Functions, секрета и n8n

  1. Создайте секрет `YC_N8N_WEBHOOK_SECRET` в Cloud Functions и в окружении n8n.
  2. В Cloud Functions добавьте HMAC-подпись по timestamp и raw body.
  3. Импортируйте workflow JSON и включите production webhook URL.
  4. Создайте таблицу idempotency с unique index по `idempotency_key`.
  5. Настройте маршруты по `event_type` и alert на invalid signature.

Тесты перед production и проверка подписи

curl -X POST "https://YOUR-N8N-DOMAIN/webhook/yandex-cloud-functions-to-n8n" \
  -H "Content-Type: application/json" \
  --data @yandex-cloud-functions-to-n8n-payload.json
  1. Отправьте корректное событие с валидной подписью.
  2. Повторите тот же `event_id` и проверьте, что бизнес-действие не повторилось.
  3. Измените один символ payload после подписи: workflow должен отклонить запрос.
  4. Отправьте старый timestamp и проверьте защиту от replay.
  5. Проверьте ошибку downstream API: n8n должен залогировать событие и отправить alert.

Production-риски serverless webhook-прокси

  • Секрет прошит в коде функции. Используйте переменные окружения и секреты, а не строку в репозитории.
  • Сравнение подписи обычным `===`. Для HMAC лучше constant-time compare, чтобы не открывать timing-атаки.
  • Нет idempotency. Повторная доставка serverless-события запускает бизнес-действие дважды.
  • Функция ждёт долгий workflow. Пусть n8n отвечает быстро, а долгие операции уходят в отдельную очередь или sub-workflow.
  • Логи содержат payload с PII. Маскируйте персональные данные и не пишите секреты в execution data.

См. также Webhook signature validation, idempotency keys, webhooks API gateway и error workflow alert. Официальные документы: Yandex Cloud Functions, Cloud Functions triggers и n8n Webhook node.

Карточка проверенного события Yandex Cloud Functions в n8n
Визуальная карточка показывает результат проверки подписи, возраста события и idempotency.

Критерии готовности

  1. Все запросы от Cloud Functions подписаны HMAC.
  2. n8n отклоняет старые timestamp и invalid signature.
  3. Повторный event_id не запускает бизнес-действие второй раз.
  4. Секрет хранится в ENV/secret manager, а не в workflow description.
  5. Ошибки downstream API попадают в alert и audit log.
Нужно безопасно связать Yandex Cloud и n8n?

Nodbot настроит защищённый webhook ingress: Cloud Functions, HMAC, idempotency, retry, alerting и маршрутизацию событий в ваши workflow.

Обсудить serverless-интеграцию