Lesson 20 / 25
Securing Webhooks and Credentials
Authenticate webhook calls, verify signatures and protect the encryption key.
A public URL is an open door
Anyone who finds a webhook URL can trigger it. Turn on authentication on the Webhook node (Header Auth or Basic Auth), or verify a signature that the sender computes over the request body with a shared secret. Also protect the instance itself: serve it over HTTPS, do not expose the editor publicly without access control, and keep the N8N_ENCRYPTION_KEY safe, because credentials in the database are encrypted with it.
Verifying an HMAC signature
Run this in a Code node. timingSafeEqual compares in constant time. This ran in Node.js: the SHA-256 hex digest is 64 characters long and an unmodified body matches. In a real flow you compare against the signature header sent by the caller, using the raw body.
const crypto = require("crypto");
const secret = "s3cret"; // from a credential, not hard-coded
const body = '{"event":"paid"}';
const expected = crypto.createHmac("sha256", secret).update(body).digest("hex");
const received = expected; // in a real flow: the header value
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
console.log(expected.length, ok);
Output:
64 true
Back up the encryption key
If you lose N8N_ENCRYPTION_KEY, saved credentials cannot be decrypted. Set it explicitly via an environment variable, store it in a password manager, and never commit it to Git.
Quick check: What does enabling authentication on a Webhook node prevent?
- The workflow from ever running
- Anyone with the URL triggering the workflow
- The use of JSON
- Logging
Answer
Anyone with the URL triggering the workflow — Only callers who present valid credentials or signatures can trigger it.