n8n public webhook no authentication – how to add basic auth or header verification

Step by Step Guide to solve insecure webhook exposure 
Step by Step Guide to solve insecure webhook exposure


Who this is for: Developers and DevOps engineers who run n8n in production and need to lock down public webhook endpoints. We cover this in detail in the n8n Security & Hardening Guide.


Quick diagnosis

Publicly reachable n8n webhook URLs can be invoked by anyone on the Internet. An attacker can trigger workflows, exfiltrate data, or launch privilege‑escalation chains simply by sending a HTTP request to the raw webhook endpoint.

Featured‑snippet solution – Immediately limit webhook access by (1) enabling basic‑auth or JWT on the n8n server, (2) restricting the endpoint to a trusted IP range via a reverse‑proxy or firewall, and (3) rotating the webhook secret after each deployment.


1. How n8n webhooks become public ?

If you encounter any default credentials vulnerability resolve them before continuing with the setup.

Exposure vector What it looks like Typical impact
Direct internet‑facing port (e.g., 0.0.0.0:5678) https://example.com/webhook/12345 reachable from any IP Unauthenticated workflow execution, data leakage
Reverse‑proxy mis‑configuration (missing auth, open allow all) Nginx/Traefik passes all traffic to /webhook/* Same as above, plus potential DoS
Cloud‑exposed URL (e.g., Ngrok, Vercel preview) left active Temporary tunnel URL still alive after dev session One‑off abuse, but can persist if tunnel not closed
Logging the full URL (including secret) in plain text INFO: Webhook URL: https://.../webhook/abcd?token=secret Secrets harvested from logs, later replay attacks

EEFA note: In production, never expose the raw webhook URL without an additional authentication layer. Even a “secret” query param is not sufficient because it can be harvested from logs, browser history, or referer headers.


2. Step‑by‑step hardening of n8n webhook endpoints

2.1 Enable built‑in HTTP basic authentication

Add the following environment variables (or Docker‑compose overrides) and restart n8n:

# .env or docker-compose.yml
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=webhookadmin
N8N_BASIC_AUTH_PASSWORD=$(openssl rand -base64 32)   # store securely

EEFA: Use a strong, randomly generated password and rotate it every 90 days. Do not commit the .env file to source control. If you encounter any environment variable secrets leakage resolve them before continuing with the setup.

2.2 Restrict access with an IP allow‑list (NGINX example)

Server block – SSL termination (excerpt):

server {
    listen 443 ssl;
    server_name n8n.example.com;

    # SSL certs omitted for brevity
}

Location block – IP whitelist and auth header forwarding:

location /webhook/ {
    allow 203.0.113.0/24;   # corporate subnet
    deny all;               # block everyone else
    proxy_set_header Authorization $http_authorization;
    proxy_pass http://localhost:5678;
}
Directive Effect
allow 203.0.113.0/24; Whitelists corporate subnet
deny all; Blocks every other source IP
proxy_set_header Authorization Passes the basic‑auth credentials to n8n

EEFA: When using a cloud firewall (AWS SG, GCP firewall rules, Azure NSG), replicate the same CIDR restrictions at the network layer for defense‑in‑depth.

2.3 Rotate webhook secrets automatically

Generate a fresh token (run during CI/CD):

WEBHOOK_TOKEN=$(openssl rand -base64 32)

Inject the token into the n8n container:

# docker‑compose override
environment:
  - N8N_WEBHOOK_TOKEN=${WEBHOOK_TOKEN}

Reference the token inside a workflow node (JSON snippet):

{
  "url": "https://n8n.example.com/webhook/{{ $env.N8N_WEBHOOK_TOKEN }}",
  "method": "POST"
}

EEFA: Store WEBHOOK_TOKEN in a secret manager (AWS Secrets Manager, HashiCorp Vault, etc.) and grant the n8n container read‑only access. Never hard‑code it.


3. Advanced mitigation – JWT‑protected webhooks

n8n can verify a JWT before executing a workflow. Add a pre‑hook Function node that checks the token. If you encounter any jwt auth misconfiguration resolve them before continuing with the setup.

Extract and verify the JWT (first part):

const jwt = require('jsonwebtoken');
const authHeader = $json["headers"]["authorization"] || '';
const token = authHeader.replace('Bearer ', '');
if (!token) {
  throw new Error('Missing JWT');
}

Validate the token and expose claims (second part):

try {
  const payload = jwt.verify(token, $env.JWT_SECRET);
  $set('userId', payload.sub);   // optional: store for later nodes
} catch (e) {
  throw new Error('Invalid JWT');
}

Deploy the signing secret via environment variable:

N8N_ENV_JWT_SECRET=$(openssl rand -base64 48)

Why it works: The JWT is signed with a secret known only to your issuing service, preventing replay attacks and allowing fine‑grained claims (user ID, scopes).

EEFA: Use RS256 (asymmetric) for cross‑team environments; rotate the signing key annually and revoke compromised tokens immediately.


4. Monitoring & incident response

Tool What to monitor Alert threshold
n8n built‑in logs (/logs) `Webhook called` events without a valid auth header > 5 unauthenticated calls per minute
Cloud‑flare Access logs IPs outside the allow‑list hitting /webhook/* Any hit
Prometheus exporter (N8N_METRICS=true) `n8n_webhook_requests_total{status=”401″}` Spike > 200 % over 5‑min window
SIEM (Splunk, ELK) Search for webhook + error Immediate ticket

TL;DR checklist

  • [ ] Enable N8N_BASIC_AUTH_ACTIVE with a strong password.
  • [ ] Place a reverse‑proxy (NGINX/Traefik) in front and whitelist trusted IPs.
  • [ ] Store webhook secrets in a secret manager; rotate on each deploy.
  • [ ] Consider JWT validation for high‑value endpoints.
  • [ ] Set up alerts for unauthenticated webhook calls.

5. Secure n8n webhooks in 3 minutes

  1. Add basic‑auth – set N8N_BASIC_AUTH_ACTIVE=true and a random password.
  2. Restrict IPs – configure your reverse‑proxy to allow <trusted‑CIDR> and deny all.
  3. Rotate secret – generate a new WEBHOOK_TOKEN per release and keep it in a secret manager.

Result: Only authorized users or services can trigger your workflows, eliminating the “insecure webhook exposure” vector.

Leave a Comment

Your email address will not be published. Required fields are marked *