All segments

n8n Security: Lock Down Credentials Before You Scale

n8n security for store data starts with the encryption key: how credential storage, webhook exposure and execution logs put payment data at risk.

  • Published
  • Reading time 14 min read
  • Author Nafiul Hasan
n8n Security: Lock Down Credentials Before You Scale. Diagram: what leaks, and what comes back. RUN n8n Security: Lock DownCredentials Before You Scale pointerflow.com

Short answer

Locking down n8n security starts with the encryption key that protects stored credentials, followed by taking the webhook endpoint off the open internet, replacing default logins with real authentication, keeping the instance patched on a schedule, and limiting what execution logs retain about customer and payment data.

What n8n security means once real credentials are in it

A self-hosted n8n instance that only moves test data between demo apps does not need much of a security posture. One that holds your Shopify Admin API token, your payment processor’s secret key and a customer database credential is a different animal: it’s now a single machine that, if compromised, gives an attacker roughly the same reach your finance and support teams have. n8n security, on an instance handling real store data, is not really about the workflow builder itself. It comes down to four things underneath it: how credentials are stored at rest, how reachable the webhook endpoint is from the open internet, who can log in, and what gets left behind in the execution log after a workflow runs. Get those four right and the rest of the hardening work is routine maintenance. Get the encryption key wrong, and the rest doesn’t matter much.

Who this guide is for, and who should sit this one out

This guide is written for the team running n8n against production systems: order webhooks from Shopify, a payment gateway’s API, a customer data platform, maybe a warehouse management system. If your instance only touches internal spreadsheets and Slack notifications, most of this still applies, but the stakes are lower and you can move through it faster. If you’re running n8n as a personal experiment with no real credentials attached yet, none of this is urgent this week. And if you’re below the point where a paid subscription platform and a dedicated person responsible for infrastructure make sense, meaning roughly under $3M in revenue, the honest answer is that a hosted automation tool, with someone else on the hook for patching, is probably the better trade than taking on a self-hosted instance at all. This guide assumes you’re past that point: on Shopify Plus or an equivalent paid platform, with enough transaction volume that a leaked credential is a real incident and not a hypothetical one.

What you need before you start

Before touching any settings, get four things in place. Admin access to the host running n8n, whether that’s a VM, a container platform or a managed server, with the ability to set environment variables and restart the process. A secrets manager, or at minimum an encrypted storage location separate from your regular database backups, to hold the encryption key and any credentials you rotate during this work. A reverse proxy or load balancer capable of TLS termination and path-based routing, if you don’t already have one in front of n8n. And an inventory of every credential currently stored inside the instance, so you know what’s actually exposed while you work through the rest of this: which API tokens, which OAuth connections, which database logins, and which of those touch payment or customer data directly.

How n8n stores your credentials, and why the encryption key matters most

n8n encrypts credential values before writing them to its database, using a key it either generates itself on first start or reads from an environment variable you set. If you never set that variable, n8n creates the key automatically and stores it in a local config directory on the host. That’s fine for a laptop running test workflows. It’s a genuine risk for a production instance, because the key then exists in exactly one place, on one disk, usually never backed up on its own.

A lost encryption key doesn’t just cause an inconvenience. It makes every credential n8n has encrypted unreadable at once, not individually recoverable. You’d need to re-enter every API token, every OAuth connection and every database login stored in the instance, on every workflow that uses one, from scratch. There’s no partial recovery: the key either decrypts everything it was used to encrypt, or it decrypts nothing.

Rotating the key deliberately has the identical effect, which is worth saying plainly because it surprises people who expect key rotation to work the way it does with, say, an API token that has an overlap window. It doesn’t here. Change the encryption key and every credential encrypted under the old one stops working the moment you restart with the new one. If you do decide to rotate, and there are good reasons to (a suspected compromise, an employee departure who had access to the key, a migration to a proper secrets manager), treat it as a scheduled maintenance window where you budget time to re-authenticate every connected service in one sitting, not as something you slot in between other tasks.

Set and back up the encryption key properly

Generate the key explicitly rather than letting the default behaviour create one for you. Use a proper random generator to produce a long value, at least on the order of 32 bytes, rather than typing something memorable; a memorable key is a guessable one, and there’s no reason for a human to ever need to type this value from memory. Set it as the encryption key environment variable before the instance’s first start, or before a deliberate rotation, using whatever mechanism your host supports for injecting environment variables at process start, whether that’s a container orchestrator’s secrets feature, a .env file with restricted permissions, or your platform’s own secrets manager integration.

Store a second copy somewhere your incident response process can reach even if the host itself is unavailable: a password manager with restricted access, or a dedicated secrets vault, not a text file sitting in the same directory as your workflow exports. This matters more than it sounds like it should. The most common failure here isn’t a sophisticated attack; it’s a database backup and the encryption key ending up in the same storage bucket or the same git repository, because whoever set up backups treated the key as just another config value. An attacker who gets both gets a decrypted view of everything. An attacker who gets only the encrypted database gets nothing usable. Keep them apart, and audit where each one actually lives at least once, because “we back it up somewhere” is not the same as knowing where.

Take the webhook endpoint off the open internet

n8n’s webhook nodes create an endpoint reachable at a path under your instance’s public URL, and for most production workflows, that endpoint being public is the entire point of it: Shopify, your payment gateway, or a customer data platform push events to it as things happen in the real world, which is exactly what a one-way integration needs. The fix here isn’t to hide the endpoint. It’s to control what an unauthenticated request to it can actually do.

Start with the network path. Run n8n behind a reverse proxy that terminates TLS and only forwards the specific paths you actually use, the webhook path and the editor path, rather than exposing the whole application surface directly to the internet. This alone rules out a lot of casual scanning traffic that would otherwise hit endpoints you never intended to be public.

Next, verify signatures. Most vendors that push webhooks to a third-party system sign the request body with a shared secret, precisely so the receiving system can confirm the request genuinely came from them and hasn’t been tampered with in transit. Enable that verification on every webhook node that supports it, so a request without a valid signature never reaches your workflow’s actual logic, whether that’s writing to your order database or triggering a refund. A webhook node that accepts anything sent to its URL is trusting the URL’s obscurity as its only defence, and a URL is not a secret once it’s been used in a vendor dashboard, a support ticket, or a Slack message.

Where the vendor publishes source IP ranges for their webhook infrastructure, add an allowlist at the proxy layer as a second control. Shopify and several payment gateways publish these ranges; check the current version on the vendor’s own documentation rather than trusting a list you find elsewhere, since these ranges do change. Rate-limit the endpoint too, so a retry storm from a misbehaving integration, or a scan, doesn’t queue thousands of executions and choke the instance for everyone else using it.

Finally, be disciplined about test versus production paths. n8n’s test webhook URLs behave differently from production ones and are genuinely useful while you’re building a workflow, but they’re also easy to leave active after the workflow ships, because nothing forces you to go back and disable them. Get in the habit of confirming a test URL is switched off once a workflow goes live, and never point a real vendor integration at a test path as a long-term arrangement because it happened to work during development.

Replace default login with real authentication

Modern self-hosted n8n supports individual accounts with email and password login and an owner role, which has largely replaced the older approach some earlier deployments used of a single shared login for the whole editor. Exactly which setting controls this, and what the defaults are, has changed across releases, so check your version’s current documentation before assuming anything about what’s active out of the box.

What doesn’t change across versions is the operational discipline. Claim the owner account the moment the instance is stood up; don’t leave a fresh install reachable on the network with its setup wizard uncompleted, even briefly, because that’s a window where anyone who finds the URL can claim ownership themselves. Create individual accounts for each person who needs access, rather than one shared login passed around in a chat message, so that when someone leaves the team you can revoke their access specifically instead of rotating a password everyone else also has to learn.

If your organisation already runs an identity provider and wants single sign-on into n8n, check whether your licence tier includes it before building a workflow around the assumption that it does; self-hosted community deployments and licensed editions differ on this, and the current pricing and licensing page is the place to confirm it, not a general assumption carried over from another tool. Whatever authentication you land on, put the editor UI itself behind the same access boundary, VPN or IP allowlist, as any other internal admin tool your team runs. There’s no reason the interface that can read and edit every stored credential should be reachable from anywhere a browser can reach the internet.

Put a patching cadence on the calendar

Self-hosting means you own the update process; there’s no vendor SRE team pushing a fix to your instance overnight. n8n ships releases on a regular basis, and some of those releases carry fixes to things that matter specifically for security, not just new nodes or UI changes. “If it isn’t broken, don’t touch it” is a reasonable instinct for a lot of software, but it’s the wrong instinct for an instance sitting next to payment and customer data, because a known issue that’s been patched upstream doesn’t stop being exploitable just because nothing has visibly gone wrong yet on your instance.

Set a fixed cadence rather than waiting for a prompt. Checking monthly is a reasonable default for most teams at this size; checking weekly is defensible if your instance is genuinely central to order or payment flow. When a new release lands, read its notes specifically for anything flagged as a security fix, not only the headline features, and treat those with more urgency than a routine version bump.

Before touching production, run the new version against a staging copy: a separate instance with its own database and its own encryption key, populated with a representative set of workflows, so a breaking change in the new release surfaces there first rather than against real orders. This matters more with n8n than with some tools, because node behaviour and configuration options do shift between versions, and a workflow that runs cleanly on the old version can fail silently, or worse, fail loudly mid-checkout, on the new one if you skip staging. If you’ve fallen several versions behind, read the changelog for each minor version you’re jumping across, not just the one you’re landing on, since a breaking change introduced two versions ago still applies to you.

Patch the host underneath n8n on the same schedule: the operating system, and if you’re running it in a container, the base image the container is built from. A perfectly patched n8n application sitting on an unpatched host operating system, or an old base image with known vulnerabilities baked into it, is still an exposed instance.

Decide what your execution log is allowed to keep

Every workflow execution in n8n records, by default, the data that passed through each node during that run, precisely so you can open it later and see what happened when something breaks. That’s genuinely useful for debugging. It’s also, on an instance wired into your store, the same log that now contains whatever your webhook received: a customer’s email address and shipping details from an order-created event, a payment token reference and card metadata from a payment event, potentially a full cart’s contents from a checkout workflow. Treat that execution log the same way you’d treat a database with customer PII and payment metadata sitting in it, because functionally, that’s exactly what it is, and it deserves the same retention discipline you’d apply to any other system holding that kind of data.

Configure execution data retention so that old runs are pruned automatically after a defined window, rather than accumulating indefinitely with no expiry and no one responsible for them. Exactly which setting controls this, and whether it lives in an environment variable or the instance’s own settings UI, has moved between releases, so check your current version’s documentation for the specific mechanism rather than assuming a name from an older setup guide.

Beyond retention, be selective about what gets saved in the first place. Not every workflow needs its successful execution data kept at all; turn that off for workflows you’ve already validated and don’t actively debug, and keep it on only for the ones you’re still actively working through. Where a specific node handles a payment token or another sensitive value, check whether that node’s output includes the full response body or a redacted one, and prefer a credential reference over passing the raw value through the workflow as ordinary data wherever the integration supports it. Finally, restrict who can view the execution list itself. It should sit behind the same access tier as your CRM or your order management system, not be visible to everyone with general engineering access to the instance, because the execution list is, in practice, a searchable log of customer and payment activity even though nobody built it to be one on purpose.

The setting most teams get wrong

Two things, and they’re related. The first is the encryption key: teams stand up n8n, connect their first few credentials, and never come back to explicitly set the key, so it sits auto-generated on a single disk with no backup, for months, until someone asks during a security review and nobody can say for certain where it lives or whether it’s backed up. The second, and the one that gets missed even by teams who do handle the key properly, is execution data retention. It’s treated as inert debug output, something you’d only look at if a workflow breaks, and it’s left on its default settings indefinitely because nothing about a growing execution log is visibly broken. Nobody decides to keep months of customer addresses and payment metadata sitting in a database with no formal owner; it just happens, one un-pruned execution at a time, because retention was never a decision anyone made on purpose.

How to verify your instance is actually locked down

Work through this as a checklist rather than taking any of the previous sections on faith. Confirm the encryption key was set explicitly rather than auto-generated, and confirm a copy exists somewhere outside your primary database backup, in a location someone other than you could find in an emergency. Send a request to the webhook URL from outside your network without a valid signature and confirm it’s rejected at the workflow level rather than silently queued and executed. Try logging into the editor UI with no credentials shared over chat, confirming each team member has their own account and the original setup account has been claimed. Check the running version against the project’s current release notes and note, honestly, how many releases behind you are and what’s in the ones you’ve skipped. Open the execution list for every workflow that touches customer or payment data and confirm you can state, for each one, how long its execution data is retained and why that window was chosen, not just that it exists.

Why this is an automation-governance problem, not just an infrastructure one

Locking down the instance is necessary work, but it doesn’t answer a different question: what is the automation itself allowed to decide on its own, once the platform underneath it is secure? A workflow that correctly rejects an unsigned webhook request can still auto-tag a customer as fraudulent from one ambiguous signal, or retry a failed payment call in a way that double-charges a card, and neither of those is something an encryption key or a firewall rule fixes. That’s a question of who owns what the automation is trusted to act on without a human checking first, which is a design decision, not a security setting. It’s the problem Pointerflow’s AI agents and automation work is built to own alongside the platform hardening covered here, so the instance isn’t just secure, it’s trustworthy with what it’s allowed to do.

Sources

  • No external figures are quoted in this article. It’s written from n8n’s documented product behaviour (credential encryption, webhook handling, user management and execution data) and general self-hosted infrastructure security practice.

Frequently asked

Where does n8n store the encryption key by default?

If you don't set one explicitly, n8n generates an encryption key on first start and writes it to a local config directory on the host machine. That's workable for testing but risky for a production instance, because the key then exists in exactly one place with no backup. Set it explicitly instead and store a copy in a secrets manager.

What happens if I lose the n8n encryption key?

Every credential n8n has encrypted becomes unreadable. You can't decrypt existing API tokens, OAuth connections or database logins stored in the instance; you have to re-enter each one from scratch on every workflow that uses it. There's no recovery path around a lost key, which is why it needs its own backup, separate from the database.

Can I rotate the n8n encryption key without breaking anything?

No. Rotating the key deliberately has the same effect as losing it: every credential encrypted under the old key stops decrypting under the new one. Plan a rotation as a maintenance window where you re-authenticate every connected service, not as a routine change you make casually or on a schedule.

Is it safe to expose n8n's webhook endpoint to the internet?

It has to be reachable for vendors such as Shopify or a payment gateway to push events to it, so exposure itself isn't optional. What matters is control: terminate TLS at a reverse proxy, verify each webhook's signature before your workflow logic runs, and allowlist vendor source IP ranges where they're published.

Does n8n support single sign-on for self-hosted instances?

SSO and SAML support depend on your licence tier and version, and this has changed across releases, so check n8n's current documentation and pricing page rather than assuming your setup includes it. Community edition and licensed self-hosted deployments differ here.

How often should I patch a self-hosted n8n instance?

Check for new releases against a fixed schedule, for example monthly, rather than waiting for a workflow to break. Read the release notes for security-relevant fixes specifically, test the upgrade against a staging copy first, and patch the host operating system and container image on the same cadence.

What kind of data ends up in an n8n execution record?

By default, an execution record stores the data that passed through each node during that run, so you can inspect it while debugging. For a workflow handling a Shopify order or a payment event, that can include a customer's contact details, shipping address, and payment metadata from the trigger payload.

Can execution logs contain customer payment data?

Yes. If a workflow's trigger or a node in it receives payment metadata such as a token reference or the last digits of a card, that data is captured in the execution record along with everything else the node handled, unless you've configured retention and logging settings to limit it.

How long should I keep n8n execution data?

There's no single right answer; it depends on how long you genuinely need a run for debugging and what your data-retention policy for customer and payment information already requires elsewhere. Configure automatic pruning so executions are deleted after a defined window rather than accumulating indefinitely with no owner.

Do I need a web application firewall in front of n8n?

A WAF isn't mandatory, but a reverse proxy that terminates TLS, restricts which paths are forwarded, and applies rate limiting covers most of the same ground for a self-hosted instance. Add a WAF if your team already runs one for other services and can maintain its rule set.

What's the biggest security mistake teams make with self-hosted n8n?

Leaving the encryption key to auto-generate instead of setting it explicitly, and never revisiting execution data retention once real credentials and customer data are flowing through the instance. Both are one-time settings that get skipped during setup and then forgotten because nothing visibly breaks.

Should test and production webhooks use different security settings?

Yes. Test webhook URLs in n8n behave differently from production ones and are easy to leave active after you've finished building a workflow. Treat a test URL as temporary, confirm it's disabled once the workflow goes live, and never point a real vendor integration at a test path long-term.

Is n8n cloud more secure than self-hosting?

n8n's hosted cloud offering shifts patching, key management and infrastructure security to the vendor, which removes several of the responsibilities covered here. Self-hosting trades that convenience for control over where data lives; which is right for you depends on your compliance requirements, not on which option is inherently safer.

Who shouldn't self-host n8n for production workflows?

A team without anyone responsible for patching, backups and access control shouldn't run production credentials through a self-hosted instance. If that's your situation, a hosted platform where someone else owns those responsibilities is the safer default until you have the operational capacity to own them yourself.

Next step

Is this your ai agents & automation problem, or a symptom of another one?

Bring your numbers — the churn split, the decline rate, whatever your flows are earning — and we will tell you which of them is the expensive one.

Book a call →