Agentic AI expands the security boundary of workflow automation. An n8n agentic workflow does not just generate an answer. It uses stored credentials to act across source control, databases, cloud platforms, AI providers, and SaaS applications. A leaked n8n API key is therefore only the beginning of the attack path.
At the center of that access is a single root of trust: the N8N_ENCRYPTION_KEY.
Our research examined how an attacker could move from initial API access to that key and the credentials it protects. We found three weaknesses in the way n8n derives signing and session secrets, demonstrated how weak encryption keys can be recovered offline from public artifacts, and identified 129 internet-accessible instances using known weak keys.
We also reproduced an attack using CVE-2026-25053 that allowed an API key associated with a sufficiently privileged account to be escalated into access to the encryption key and encrypted credential records.
The result is a concrete picture of the risk behind agentic automation: the more systems an agent can reach, the more consequential a failure in its credential and execution layer becomes. This report traces the attack chain from exposed API credentials to encryption key compromise, then provides a hardened configuration designed to break it at multiple points.
The N8N_ENCRYPTION_KEY is n8n's root of trust
At the time of this research, n8n had received 48 CVEs since January 2026. Several allowed attackers to escape the workflow execution environment and gain code execution or filesystem access on the host.
Once an attacker reaches the filesystem, two assets become primary targets:
~/.n8n/database.sqlite, which contains stored credentials in encrypted form on default SQLite deployments- The
N8N_ENCRYPTION_KEY, provided through the environment or stored in the n8n configuration, which decrypts them
Together, they provide offline access to the plaintext value of every credential stored in the database.
The encryption key also carries responsibilities beyond credential encryption. In the implementation we analyzed, it contributes to the secret used to sign JSON Web Tokens and to the value used to generate the public instance ID.
Concentrating those functions in one key makes it the central trust anchor for an n8n instance. Compromising it can affect stored credentials, token integrity, session authentication, and the confidentiality of every connected integration.
Our analysis identified three weaknesses in that trust model.
Three weaknesses in n8n's key derivation and session authentication
Flaw 1: JWT secret derivation discards half the key
The JWT signing secret is derived from the N8N_ENCRYPTION_KEY by taking every other character.
Under this derivation path, a 32-character encryption key produces a 16-character signing secret. Half of the input characters make no contribution to the derived value, reducing its effective entropy.
The practical severity depends heavily on how the original encryption key was generated. A long, randomly generated key remains difficult to recover. A short or human-memorable value is much more vulnerable to offline guessing.
Flaw 2: Sessions can be forged for OIDC-provisioned users
For users provisioned through OpenID Connect, n8n stores the literal string "no password set" in the password field.
The n8n-auth session token is derived using this password value and the N8N_ENCRYPTION_KEY. Because the password component is known, an attacker who obtains or recovers the encryption key can reproduce the derivation and forge a session for an OIDC-provisioned user without knowing that user's identity provider password.
Flaw 3: Sessions can be forged for pending users
Invited users who have not completed registration have a null password value.
During session derivation, JavaScript coerces that null value into an empty string. As with OIDC-provisioned users, the password component becomes predictable.
An attacker with the encryption key can therefore derive a valid session token for a pending user without knowing a password.
These weaknesses do not reveal the encryption key on their own. Their impact emerges when the key is exposed through a vulnerable host, recovered from weak key material, or obtained through another attack path.
Recovering weak encryption keys offline
The N8N_ENCRYPTION_KEY is often generated automatically, but self-hosted administrators can replace it with a custom value. When that value is human-memorable or follows a predictable pattern, public artifacts can make offline recovery possible.
A leaked n8n JWT acts as a verification oracle.
An attacker can generate a candidate encryption key, apply n8n's JWT secret derivation, and test whether the leaked token's signature verifies. A successful verification confirms that the candidate produces the correct signing secret.
Before n8n v2.25.6, unauthenticated requests to GET /rest/settings could also return the public instance ID, which was derived from the same encryption key. That provided a second independent way to confirm a candidate. Based on our validation, that public instance ID behavior was no longer present in the same form beginning with v2.25.6.
Once the JWT and instance ID had been collected, testing key candidates required no further requests to the target.
We evaluated the exposure at scale:
- 31,793 n8n instances identified through Shodan
- 4,398 instances exposing their public instance ID
- 13.8% of the observed instances affected
- 129 internet-accessible instances whose IDs matched known weak
N8N_ENCRYPTION_KEYvalues previously exposed on GitHub
These were not merely instances that had once used weak keys. At the time of testing, the public artifacts still matched the known key patterns.
Leaked API keys provide a realistic starting point
Weak encryption keys provide one route to n8n's root of trust. Leaked API tokens provide another starting point, particularly when they belong to users who can create or modify workflows.
In a separate scan of public GitHub commits, we identified 4,576 unique n8n API tokens associated with 1,255 hostnames. Of the 896 instances reachable at the time of testing, 321 accepted at least one exposed token.
That represents approximately 36% of the reachable instances and 26% of all hostnames identified in the commits.
A valid token provides access according to the permissions of the user who created it. Many exposed tokens appeared to belong to owners or administrators, likely because those were the users configuring integrations and committing API credentials.
Depending on those permissions, an attacker may be able to enumerate users, read complete workflow definitions, inspect execution data, list stored credential objects, create workflows, or activate new automations.
Against a fully patched instance, that functionality can already be enough to abuse stored credentials or expose sensitive workflow data. Against a vulnerable instance, the same API access can become the first step toward host and encryption key compromise.
CVE-2026-25053 demonstrates that escalation path.
CVE-2026-25053: From workflow access to arbitrary file read
CVE-2026-25053 is a critical vulnerability in n8n's Git node. It affects versions earlier than 1.123.10 in the 1.x line and earlier than 2.5.0 in the 2.x line.
The vulnerability allows an authenticated user with permission to create or modify workflows to execute system commands or read arbitrary files accessible to the n8n process. n8n fixed it in versions 1.123.10 and 2.5.0.
For our proof of concept, we focused on the arbitrary file-read path.
The Git command-line option --pathspec-from-file=<file> instructs Git to read path specifications from another file. When Git attempts to stage a path that does not exist in the repository, it includes that path in an error message.
The behavior can be used to disclose a file one line at a time.
repo.git $ echo 'Hello\nGitGuardian' > /tmp/hello.txt
repo.git $ git add --pathspec-from-file=/tmp/hello.txt
fatal: pathspec 'Hello' did not match any files
repo.git $ touch Hello
repo.git $ git add --pathspec-from-file=/tmp/hello.txt
fatal: pathspec 'GitGuardian' did not match any filesThe first command reveals Hello, the first unmatched line in the target file. After a file named Hello is created in the repository, Git moves to the next path and reveals GitGuardian.
The same behavior can be reproduced through an n8n workflow.
An attacker with a valid API key associated with an account that can create or modify workflows can:
- Clone an empty attacker-controlled GitHub repository using the Git node.
- Configure the Git node to attempt to add a path literally named
--pathspec-from-file=/home/node/.n8n/config. - Read the first line of the configuration file from the resulting Git error.
- Create a file in the repository whose name matches that line.
- Pull the new file into the workflow's local repository.
- Repeat the Git operation to reveal the next line.
- Continue until the line containing the encryption key is disclosed.
The first error may reveal the opening { of the JSON configuration. Once a file named { exists in the repository, the next operation advances to the following line, which may contain the N8N_ENCRYPTION_KEY.

The official advisory describes the vulnerability as allowing arbitrary file reads, placing any file readable by the n8n process within scope. On a default SQLite deployment, that can include both /home/node/.n8n/config and the n8n database.
The configuration provides the encryption key. The database provides the encrypted credential records. Together, they allow an attacker to decrypt the stored credentials offline.
The attack chain is therefore:
Leaked API token → workflow creation → Git node exploitation → filesystem access → encryption key and credential database → offline credential decryption
The API token alone does not directly decrypt every credential. It provides the authenticated foothold needed to reach a vulnerable node. The encryption key and encrypted credential records complete the compromise.
Responsible disclosure
GitGuardian made several disclosures directly to n8n during the research.
n8n acknowledged the reports, said it was aware of the issues and planned to address them, and subsequently closed the reports. At the time of publication, GitGuardian had not independently confirmed that all changes related to the cryptographic findings had been released.
How to harden an n8n instance
n8n is not only an automation service. It is a credential store and execution environment connected to systems across the organization.
Hardening it requires controls at the instance, identity, node, runner, and credential layers.
Separate instances by trust boundary
Treat each n8n instance as a credential store for a defined team, business unit, or application boundary.
A single shared instance concentrates every connected credential and dataset behind one administrative plane. If one token, workflow, or encryption key is compromised, the blast radius includes every integration available to that instance.
Limit each deployment to the users, workflows, data, and credentials it genuinely needs.
Patch critical vulnerabilities immediately
Subscribe to the n8n security advisory feed and treat critical vulnerabilities as urgent patches.
CVE-2026-25053 is patched in versions 1.123.10 and 2.5.0. The official advisory recommends upgrading, restricting workflow editing to trusted users, disabling the Git node where it is unnecessary, and reducing operating system and network privileges.
In deployments that expose the n8n:config:sentry metadata tag, an unauthenticated visitor may also be able to determine the running n8n version. That allows attackers to identify potentially applicable CVEs before authenticating.
Do not rely on version obscurity as a control.
Keep the API and administrative interface private
Place the n8n instance and public API behind a VPN, or strict network allowlist.
If the public REST API is not required, disable it. n8n provides separate controls for disabling the API and its Swagger-based playground:
N8N_PUBLIC_API_DISABLED=true
N8N_PUBLIC_API_SWAGGERUI_DISABLED=truen8n explicitly recommends disabling the public API when it is not in use.
Disabling the API removes the initial-access surface used in the API-token attack paths, although it does not protect against compromised interactive user sessions or other exposed endpoints.
Use independent, randomly generated secrets
Generate the N8N_ENCRYPTION_KEY using a cryptographically secure random source. Do not use a company name, project name, password, or other human-memorable string.
Configure a separate random N8N_USER_MANAGEMENT_JWT_SECRET rather than allowing authentication-related signing material to depend on the encryption key.
The two values must be generated independently. Reusing the same value preserves the single-root-of-trust problem.
n8n's official self-hosted AI starter kit includes separate N8N_ENCRYPTION_KEY and N8N_USER_MANAGEMENT_JWT_SECRET configuration values.
Isolate code execution
Use external task runners so code from the Code node executes in a separate container rather than inside the core n8n process.
n8n recommends external runner mode for stronger separation between workflow code and the main application. The runner should use a dedicated, randomly generated authentication token and operate with restricted filesystem and network permissions.
In n8n 1.x, task runners must also be explicitly enabled. From n8n 2.0 onward, the separate enablement variable is deprecated, but external mode still requires a separate runners deployment.
Disable unnecessary high-risk nodes
Nodes that can execute commands, run code, connect over SSH, manipulate repositories, or read local files deserve particular scrutiny.
Use NODES_EXCLUDE to remove unnecessary nodes from the instance:
NODES_EXCLUDE='[
"n8n-nodes-base.executeCommand",
"n8n-nodes-base.ssh",
"n8n-nodes-base.git",
"n8n-nodes-base.code"
]'n8n documents NODES_EXCLUDE as the supported mechanism for preventing users from accessing specified nodes. The official guidance for CVE-2026-25053 specifically recommends disabling the Git node when it is not required.
Removing the Git node closes the CVE-2026-25053 path described in this report. It does not replace patching, and it does not address other nodes that may provide equivalent host or network access.
Only exclude the Code node if workflows do not require it. Where it remains enabled, run it through external task runners and preserve the default-deny approach to imported modules.
Restrict modules available to code
n8n blocks external module imports in the Code node unless they are explicitly allowed.
Leave NODE_FUNCTION_ALLOW_EXTERNAL unset unless a workflow has a documented requirement for a specific dependency. Allow only the minimum required built-in modules through NODE_FUNCTION_ALLOW_BUILTIN.
In external runner mode, JavaScript and Python module allowlists belong in the task-runner configuration file rather than the main n8n container's environment.
Do not use * in production unless all workflow authors are fully trusted and the runner is isolated accordingly.
Monitor and self-audit
Run the authenticated POST /api/v1/audit endpoint on a schedule and send the results to a SIEM or another monitored destination.
The audit response can identify:
- High-risk nodes
- Nodes with filesystem access
- Unprotected webhooks
- Unused credentials
- Community-installed nodes
- Potential SQL injection exposure
- Security configuration
- The running version for CVE matching
Also collect logs outside the n8n instance. A malicious workflow may be deleted after it executes, reducing the evidence available in n8n itself.
Preserve reverse proxy, network, cloud, identity provider, source control, SaaS, and downstream API logs wherever possible.
Scope credentials and remove inline secrets
Create a dedicated API key, OAuth token, or service identity for each workflow or narrow group of workflows.
Grant only the permissions the automation requires. Do not connect n8n using organization-wide administrator credentials when a scoped service account would work.
Review GET /api/v1/credentials for unused or overprivileged credential objects, and examine workflow definitions for tokens, passwords, and keys hard-coded directly in node parameters.
GitGuardian's ggshield can scan exported n8n workflow JSON for exposed secrets before the files are stored, shared, or committed.
Use n8n's credential store rather than hard-coding values in workflows. The credential store does not eliminate risk if the instance itself is compromised, but it prevents secrets from appearing directly in workflow definitions and Git history.
A hardened n8n configuration baseline
The following example is a starting point, not a drop-in configuration for every deployment. Validate each variable against the exact n8n version and deployment model in use.
Generate each placeholder independently with a cryptographically secure command such as:
openssl rand -hex 64Store the generated values in a secret manager rather than embedding the command itself in a static .env file.
# == Root secrets
N8N_ENCRYPTION_KEY=<independently-generated-random-value>
N8N_USER_MANAGEMENT_JWT_SECRET=<different-random-value>
# Protect the local settings file where supported
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
# == Disable unnecessary external surfaces
N8N_PUBLIC_API_DISABLED=true
N8N_PUBLIC_API_SWAGGERUI_DISABLED=true
N8N_DIAGNOSTICS_ENABLED=false
# Environment-managed MCP settings are available in newer n8n 2.x versions
N8N_MCP_MANAGED_BY_ENV=true
N8N_MCP_ACCESS_ENABLED=false
# == Restrict workflow code
N8N_BLOCK_ENV_ACCESS_IN_NODE=true
# Leave module imports disabled unless explicitly required.
# In external runner mode, configure exceptions in the runner config.
NODE_FUNCTION_ALLOW_BUILTIN=
NODE_FUNCTION_ALLOW_EXTERNAL=
# == Remove unnecessary high-risk nodes
NODES_EXCLUDE='["n8n-nodes-base.executeCommand","n8n-nodes-base.ssh","n8n-nodes-base.git","n8n-nodes-base.code"]'
# == Isolate task execution
# Required in n8n 1.x; deprecated from n8n 2.0 onward
N8N_RUNNERS_ENABLED=true
N8N_RUNNERS_MODE=external
N8N_RUNNERS_AUTH_TOKEN=<separate-random-runner-secret>Example n8n configuration
This baseline interrupts the demonstrated attack paths at several points: it removes unnecessary API access, blocks the vulnerable Git-node path, separates encryption and authentication secrets, and isolates workflow execution from the core n8n process. Validate each setting against the deployed n8n version before applying it.
For n8n v2.20.0 and later, MCP settings managed through environment variables require N8N_MCP_MANAGED_BY_ENV=true; without that management flag, the related environment setting has no effect.
The root of trust defines the blast radius
n8n's security model concentrates substantial authority in the N8N_ENCRYPTION_KEY.
The key protects stored credentials, contributes to authentication-related secrets in the implementation we analyzed, and can become the difference between limited access to an automation instance and offline access to the credentials in its database.
The attack paths documented here begin in different places.
An attacker might obtain an API token from a public commit, recover a weak encryption key from exposed artifacts, or exploit a vulnerable node to read sensitive files from the host. Those paths converge on the same targets: the encryption key, the credential database, and the integrations connected to the instance.
That makes hardening a matter of breaking the chain at multiple points.
Keep the API and administrative interface off the public internet. Generate independent, high-entropy secrets. Patch critical vulnerabilities quickly. Isolate workflow execution. Disable nodes that provide unnecessary host access. Audit workflows and credentials continuously. Limit every credential to the permissions its workflow actually requires.
Automation platforms inherit the reach of every system connected to them. Their security boundary must be designed accordingly.
Secure the credentials behind your AI agents
Agentic systems can act only through the credentials and machine identities they are given. GitGuardian helps security teams find exposed secrets, understand which systems they can reach, and drive remediation before one compromised credential becomes an attack path.
Explore GitGuardian for agentic AI security