Updated · 3 min read
the short answer
How do I secure an n8n webhook?
Set Authentication on the Webhook node to Header Auth (or Basic Auth) with a long random secret, and send that header from whatever calls the workflow. For webhooks from Stripe, GitHub and similar services, verify their signature in the workflow before doing anything. Keep API keys in n8n credentials, never typed into HTTP Request nodes, so they do not end up in exported workflow files.
Why webhooks are the weak spot
A Webhook node with Authentication set to None runs the workflow for anyone who has the URL, and URLs leak through front-end code, screenshots, shared workflow files and logs. In our 2026 study we read 174 AI-built automation projects (n8n, Make and Zapier workflows, AI agents and chat bots): 10% had a webhook or endpoint anyone could call, and 9% had a serious secrets problem. If the workflow calls an AI model, sends email or writes to a database, every stranger's request does the same, on your bill.
Step 1: turn on Header Auth
In the Webhook node, set Authentication to Header Auth and create a credential with a header name and a long random value. Requests without the header get a 403 and the workflow does not run.
# make a secret
openssl rand -hex 32
# call the workflow with it
curl -X POST "https://n8n.example.com/webhook/new-lead" \
-H "X-Webhook-Secret: <the secret>" \
-H "Content-Type: application/json" \
-d '{"email":"someone@example.com"}'Step 2: verify signatures from other services
Stripe, GitHub, Shopify and others cannot send your custom header, but they sign each request. Turn on the Raw Body option in the Webhook node, compute an HMAC of the raw body with the Crypto node (or a Code node) using the provider's signing secret, and stop the workflow with an IF node when it does not match the signature header. For Stripe, the signed text is the timestamp, a dot and the raw body.
Step 3: never call a webhook from the browser
If your website calls an n8n webhook directly, the URL and any secret in that request are public. Call it from your server or an Edge Function instead, after checking the user, and add a rate limit so nobody can trigger it in a loop.
Step 4: keep keys out of workflow files
- Store API keys in n8n credentials. Exported workflows reference credentials by name and do not include the secret values.
- Keys typed straight into an HTTP Request node's headers or URL are part of the workflow and are exported, shared and committed with it.
- Before committing or sharing a workflow JSON, search it for "key", "token", "secret" and "Bearer".
Self-hosting n8n
- Keep n8n updated: it has had serious security fixes, and an old version on the internet is a target
- Put the editor behind HTTPS and a strong owner password; do not expose it on a raw IP and port
- Give each credential the narrowest permission it needs, and confirm any workflow step that sends, pays or deletes
Questions
Are n8n webhook URLs secret?
No. They are hard to guess but leak easily through browsers, logs and shared files. Treat the URL as public and require a header or signature.
What is the difference between the test and production webhook URL?
The test URL only works while you click Listen in the editor; the production URL works whenever the workflow is active. Both need authentication once the workflow is live.
Can n8n verify Stripe webhook signatures?
Yes, with the Raw Body option, a Crypto node for the HMAC and an IF node to compare it with the Stripe-Signature header. Without verification, anyone can fake a payment event.
Does this apply to Make and Zapier?
Yes. Their webhook URLs are just as public. Add a secret value the workflow checks first, and keep keys in the platform's connections, not in the steps.