n8n Node Security: Auth Nodes, Credential Config & Webhook Verification
⚡ n8n Workflow Automation T2 · Node Security
n8n Node Security: Auth Nodes, Credential Config & Webhook Verification

Every n8n node that connects to an external service relies on a credential—an encrypted authentication object stored in the database using AES‑256‑CBC encryption with an instance‑unique key. The credential framework supports eight authentication schemes: OAuth2 (with automatic token refresh via lifecycle hooks), API Key, Basic Auth, Header Auth, Bearer Token, Query Auth, Digest Auth, and SSL Client Certificates. Webhook nodes, which expose public URLs, add four verification layers—HMAC‑SHA256 signature validation, IP allowlisting, built‑in authentication modes, and community security nodes—that collectively verify sender identity, integrity, and freshness [1] [2].

AES‑256
Encryption Standard [1]
8
Auth Schemes [3]
6
Security Layers (HMAC) [2]
5.3
CVSS Score (CVE‑2025‑68949) [4]

How do n8n credential nodes handle OAuth2, API keys, and vault integration?

n8n credential nodes implement the ICredentialType interface to define authentication properties for each service. OAuth2 credentials extend a base OAuth2 class with service‑specific parameters—Client ID, Client Secret, scopes, and grant type—and n8n handles the full token lifecycle: redirect, obtain, refresh automatically via lifecycle hooks, and encrypt storage. Users click “Connect Account” in the credential panel to initiate the OAuth flow for built‑in nodes; community nodes can implement the same interface. [5] [3]

API Key credentials store the key as an encrypted password field (marked with typeOptions.password: true). For enterprise deployments, external secrets vault integration retrieves secrets at runtime from HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, or Infisical via $secrets.<vault-name> expressions — decoupling secrets from the database entirely. Self‑hosted users can also reference environment variables in credential fields using $env:VARIABLE_NAME syntax, or mount secrets from files via the _FILE suffix. For the complete credential configuration reference with vault setup and environment variable patterns, see the n8n Credential Nodes guide.

How does the n8n credential system encrypt and protect stored secrets?

The credential system uses AES‑256‑CBC encryption to protect all sensitive data at rest. The encryption flow starts when Credentials.setData() receives a plaintext object—it validates the data is an object literal, encrypts the entire JSON via Cipher.encrypt(), and stores the encrypted string in this.data. On retrieval, Credentials.getData() decrypts and returns the original plaintext. The encryption key is held in the N8N_ENCRYPTION_KEY environment variable or the .n8n/config file. [1] [6]

This key must remain constant across restarts and across all instances in a queue‑mode cluster (main, workers, webhook instances)—changing it makes all existing credentials permanently unreadable. For backup strategies, you must either back up the .n8n/config file or preserve the encryption key value alongside the database dump; without the original key, credential data in the backup is unrecoverable. The system also implements data redaction to prevent exposing secrets in the UI, project‑based sharing with role‑based access control (owner/user), credential testing to validate authentication before use, and domain restrictions to prevent unauthorized credential usage across different services. For production credential management patterns including rotation and audit, see the credential nodes configuration guide.

How do you implement HMAC‑SHA256 signature verification for production webhooks?

HMAC‑SHA256 verification is the gold standard for webhook security. The canonical six‑layer pattern chains: the Webhook node (Header Auth + Raw Body enabled), a Code node extracts the raw body as a UTF‑8 string, a Crypto node computes HMAC‑SHA256(timestamp.rawBody), a Code node performs timing‑safe comparison using crypto.timingSafeEqual(), a payload validation node whitelists expected JSON fields and rejects unexpected keys, then business logic executes only after all checks pass. Invalid requests return 403 Forbidden (signature/timestamp failure) or 400 Bad Request (payload validation failure), with no response body to avoid leaking internal logic. [2]

For replay protection, include a timestamp and optional nonce in the signed payload; the Code node rejects any request with a timestamp older than a configurable window (default: 5 minutes). While n8n’s built‑in Webhook authentication modes (Basic Auth, Header Auth, JWT) verify who is calling, they do not verify that the payload hasn’t been altered or that the request is fresh. The community Secure Webhook node (@prokodo/n8n-nodes-secure-webhook) bundles all six layers— plus IP allow/deny policies and per‑IP rate limiting—into a single hardened trigger [7]. For complete webhook authentication and payload validation walkthroughs, see the n8n Webhook Node Security guide.

How does IP allowlisting work on the Webhook node, and what are its limits?

IP allowlisting on the Webhook node restricts access to specific IP ranges configured as comma‑separated CIDR entries (e.g., 34.195.0.0/16, 54.208.0.0/15). Requests from IPs outside the list are rejected before the workflow executes, adding a network‑layer filter that complements application‑layer authentication for defense‑in‑depth. However, IP allowlisting should never be the sole security layer. [8]

A critical vulnerability: CVE‑2025‑68949 (CVSS 5.3 MEDIUM) affected n8n versions 1.36.0 through <2.2.0, where the Webhook node’s IP whitelist performed partial string matching instead of exact IP comparison. An attacker whose IP shared a partial prefix with a whitelisted address could bypass restrictions—both IPv4 and IPv6 were impacted. The fix shipped in version 2.2.0. [4] Always upgrade if you use IP allowlisting, and layer it with HMAC signature verification or JWT authentication. For the complete guide to webhook hardening combining IP filters with cryptographic verification, see the n8n Webhook Node Security guide.

How do you harden self‑hosted n8n nodes with environment variables and a reverse proxy?

Production‑grade self‑hosted hardening requires multiple layers. Basic Auth (N8N_BASIC_AUTH_ACTIVE=true with N8N_BASIC_AUTH_USER/N8N_BASIC_AUTH_PASSWORD) adds a login wall to the n8n UI and REST API—the recommended minimum layer before exposing n8n to the internet. It does not protect public webhooks, which must be secured separately with HMAC, API keys, or custom validation inside workflows. [9]

For Code‑node isolation, set N8N_BLOCK_ENV_ACCESS_IN_NODE=true to prevent Code nodes from accessing process.env, and exclude high‑risk nodes (ExecuteCommand, LocalFileTrigger) via NODES_EXCLUDE. For webhook URL security, bind n8n to 127.0.0.1:5678 so port 5678 is never directly exposed—all external traffic must pass through a reverse proxy (Nginx or Caddy) that terminates HTTPS and forwards X‑Forwarded‑For and X‑Forwarded‑Proto headers. Set N8N_PROXY_HOPS=1 so n8n correctly identifies the real client IP for IP allowlisting. Always pin Docker image versions (e.g., n8nio/n8n:2.17.7) instead of using latest, and store TLS certificates via certbot with Let’s Encrypt for auto‑renewal. For the complete self‑hosted hardening blueprint covering firewall rules, audit logging, and backup strategies, see the n8n Node Security Hardening guide.

References

This guide is for informational purposes only. For the most current and authoritative information, always refer to the official n8n website (n8n.io) and the n8n documentation. Security configurations, encryption standards, and vulnerability statuses may change over time.

Leave a Reply

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