n8n-credentials-and-security

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

n8n Credentials and Security

n8n 凭证与安全

Non-negotiables

不可妥协的规则

  1. Secrets via the credential system, never in text fields or SDK code. API keys, bearer tokens, OAuth secrets, passwords: all go through
    newCredential()
    or the node's
    credentials
    parameter. A Set node hardcoding a token and read via
    {{$json.token}}
    is a text field with extra steps.
  2. Don't ask the user for credential names, but DO tell them to verify each node. The string in
    newCredential('Label')
    is cosmetic and does NOT bind to a specific stored credential. When the workflow opens, n8n auto-assigns the most recently edited credential of that type to every node, which silently picks the wrong one if the user has more than one (e.g., two Gmail accounts, prod + staging API keys). After building, always tell the user: "Open every node that uses a credential and confirm the right one is selected from the dropdown." Pick a sensible label (
    'Gmail'
    ,
    'OpenRouter'
    ,
    'Acme API'
    ) and move on.
  3. Credential creation is the user's job, not yours. The n8n MCP doesn't expose credential creation. Tell the user the exact credential type to create in the UI, then reference it by label in your node config. Don't attempt to create credentials programmatically and don't accept secrets in chat to "set up later".
  1. 机密值必须通过凭证系统处理,绝不能放在文本字段或SDK代码中。 API密钥、Bearer令牌、OAuth机密、密码:所有这些都需通过
    newCredential()
    或节点的
    credentials
    参数处理。在Set节点中硬编码令牌并通过
    {{$json.token}}
    读取的做法,本质上还是把机密值放在了文本字段中。
  2. 不要让用户提供凭证名称,但务必告知用户验证每个节点。
    newCredential('Label')
    中的字符串仅用于显示,并不绑定到特定的已存储凭证。当工作流打开时,n8n会自动将该类型最近编辑过的凭证分配给每个节点,如果用户拥有多个同类型凭证(例如两个Gmail账户、生产环境+ staging环境的API密钥),就会悄无声息地选错凭证。构建完成后,务必告知用户:“打开所有使用凭证的节点,确认下拉菜单中选择的是正确的凭证。”选择合理的标签(如
    'Gmail'
    'OpenRouter'
    'Acme API'
    )即可。
  3. 创建凭证是用户的工作,而非你的职责。 n8n MCP不提供创建凭证的接口。告知用户需要在UI中创建的具体凭证类型,然后在节点配置中通过标签引用它。不要尝试以编程方式创建凭证,也不要在聊天中接收机密值以便“稍后设置”。

Strong defaults

推荐默认做法

  • Use native credentials when available. Every native node (Slack, Gmail, Postgres, OpenAI, etc.) has a credential type. Don't reach for generic credential types when a native option exists.
  • For multi-header or header-plus-query auth shapes, use the
    httpCustomAuth
    credential type. See
    references/CUSTOM_CREDENTIALS.md
    .
  • 优先使用原生凭证(如果可用)。 每个原生节点(Slack、Gmail、Postgres、OpenAI等)都有对应的凭证类型。当存在原生选项时,不要使用通用凭证类型。
  • 对于多头部或头部加查询参数的认证形式,使用
    httpCustomAuth
    凭证类型。详见
    references/CUSTOM_CREDENTIALS.md

The credential system

凭证系统说明

In n8n, credentials are first-class objects:
  • Stored encrypted at rest in the n8n database.
  • Referenced by ID from nodes that need them.
  • Scoped to projects (Cloud & enterprise) or shared globally (some self-hosted setups).
  • Identified by a type slug (googleSheetsOAuth2Api, slackApi, httpHeaderAuth). The slug is what nodes reference and what determines which auth fields the credential collects.
A node that needs auth has a
credentials
parameter pointing to a credential ID + type. Secret values never appear in workflow JSON. Exporting a workflow leaks the reference, not the secret.
For the full model (SDK resolution, rotation, project scoping), see
references/CREDENTIAL_SYSTEM.md
.
在n8n中,凭证是一等对象:
  • 存储时在n8n数据库中加密。
  • 需要认证的节点通过ID引用凭证。
  • 按项目划分作用域(云版及企业版)或全局共享(部分自托管部署)。
  • 通过类型标识(如googleSheetsOAuth2Api、slackApi、httpHeaderAuth)识别。该标识是节点引用的依据,同时决定了凭证需要收集哪些认证字段。
需要认证的节点会有一个
credentials
参数,指向凭证ID和类型。机密值永远不会出现在工作流JSON中。导出工作流时只会泄露凭证引用,而非机密值本身。
如需了解完整模型(SDK解析、轮换、项目作用域),请查看
references/CREDENTIAL_SYSTEM.md

Decision tree: how to authenticate this thing

决策树:如何为服务配置认证

Need to call an external service?
├── Native credential exists (Slack, Gmail, OpenAI, Postgres, ...)?
│   └── Use the native node + its credential type. Done.
├── Service is "standard-shaped" (REST + Bearer/Basic/OAuth)?
│   ├── Configure HTTP Request with one of the built-in auth types:
│   │   - Generic OAuth2
│   │   - Header Auth
|   |   - Bearer Auth (same as header auth but with only field being for actual token)
│   │   - Basic Auth
│   │   - Custom Auth
│   └── See references/HTTP_REQUEST_WITH_AUTH.md
└── Service needs multiple static headers, or headers plus query params?
    └── Use the httpCustomAuth credential type.
        See references/CUSTOM_CREDENTIALS.md
需要调用外部服务?
├── 存在原生凭证(Slack、Gmail、OpenAI、Postgres等)?
│   └── 使用原生节点及其凭证类型。完成。
├── 服务为“标准类型”(REST + Bearer/基础认证/OAuth)?
│   ├── 使用以下内置认证类型之一配置HTTP Request节点:
│   │   - 通用OAuth2
│   │   - 头部认证
|   |   - Bearer认证(与头部认证类似,但仅需填写令牌字段)
│   │   - 基础认证
│   │   - 自定义认证
│   └── 参考references/HTTP_REQUEST_WITH_AUTH.md
└── 服务需要多个静态头部,或头部加查询参数?
    └── 使用httpCustomAuth凭证类型。
        参考references/CUSTOM_CREDENTIALS.md

When the user pastes a secret into a chat

当用户在聊天中粘贴机密值时

This happens. The user types something like:
"Set up a workflow to call Acme API with bearer
sk-abc123def456
"
What to do:
  1. Don't put the token in a text field, even temporarily. A Set node that hardcodes the value and is referenced via
    {{$json.token}}
    is a text field with extra steps.
  2. You place the node, the user creates the credential from it. You can't create credentials, the n8n MCP doesn't expose that. Tell the user: "I'll add the node configured for the right credential type (e.g.
    Bearer Auth
    for bearer tokens,
    Header Auth
    for other custom auth headers). When you open it, click the credential dropdown and choose 'Create new credential', and n8n will prompt you for the token there." The credential field on the node will either be empty (no credential of that type exists yet) or auto-filled with the user's most recently edited one of that type (see non-negotiable #2).
  3. For programmatic credential creation, the MCP surface may be limited. See
    n8n-extending-mcp
    for wrapping n8n's credential APIs. The user must provide the secret value, and you should not be the persistent home for it.
  4. Treat the pasted secret as compromised, and tell the user to rotate it. Don't soften this. The token has been transmitted to the LLM provider, may persist in chat history, transcripts, and cache layers, and is now outside the user's control. Tell them: "Rotate this token as soon as the new credential is set up in n8n. Pasting a secret into chat exposes it beyond this conversation. Treat it as leaked, not just visible."
这种情况时有发生。用户可能会输入类似如下内容:
“设置一个工作流,使用Bearer令牌
sk-abc123def456
调用Acme API”
处理步骤:
  1. 不要将令牌放入文本字段,哪怕是临时的。 在Set节点中硬编码值并通过
    {{$json.token}}
    引用的做法,本质上还是把机密值放在了文本字段中。
  2. 你负责添加节点,用户通过节点创建凭证。 你无法创建凭证,n8n MCP不提供该接口。告知用户:“我会添加配置为对应凭证类型的节点(例如Bearer令牌使用
    Bearer Auth
    ,其他自定义认证头部使用
    Header Auth
    )。当你打开该节点时,点击凭证下拉菜单并选择‘创建新凭证’,n8n会提示你输入令牌。”节点上的凭证字段要么为空(尚无该类型凭证),要么自动填充用户最近编辑过的同类型凭证(参见不可妥协规则第2条)。
  3. 关于程序化创建凭证,MCP的功能可能有限。请查看
    n8n-extending-mcp
    了解如何封装n8n的凭证API。用户必须提供机密值,而你不应成为机密值的持久存储载体。
  4. 将粘贴的机密值视为已泄露,并告知用户立即轮换。 不要含糊其辞。该令牌已传输给LLM提供商,可能会保留在聊天历史、记录和缓存层中,现已脱离用户的控制范围。告知用户:“在n8n中设置好新凭证后,请立即轮换该令牌。将机密值粘贴到聊天中会使其暴露在本次对话之外。请将其视为已泄露,而非仅可见。”

When no native node exists

当不存在原生节点时

Common case: the user wants a service n8n has no node for. Use HTTP Request with appropriate auth.
  • references/FINDING_API_DOCS.md
    : discovering auth scheme, base URL, common shapes.
  • references/HTTP_REQUEST_WITH_AUTH.md
    : wiring HTTP Request to a credential.
  • references/CUSTOM_CREDENTIALS.md
    : when built-in auth types don't fit.
常见情况:用户需要使用n8n尚无对应节点的服务。使用HTTP Request节点并配置合适的认证方式。
  • references/FINDING_API_DOCS.md
    :查找认证方案、基础URL、常见格式。
  • references/HTTP_REQUEST_WITH_AUTH.md
    :为HTTP Request节点配置认证。
  • references/CUSTOM_CREDENTIALS.md
    :当内置认证类型不适用时使用。

Reference files

参考文件

FileRead when
references/CREDENTIAL_SYSTEM.md
You need to understand how credentials are stored, referenced, scoped, or rotated
references/CUSTOM_CREDENTIALS.md
Multi-header / header-plus-query auth in one credential, or per-request signing patterns (HMAC, JWT, webhook validation)
references/HTTP_REQUEST_WITH_AUTH.md
Configuring HTTP Request with auth: Bearer, Basic, OAuth, Header Auth
references/FINDING_API_DOCS.md
The user mentioned a service you don't have node-level knowledge of
文件阅读场景
references/CREDENTIAL_SYSTEM.md
需要了解凭证的存储、引用、作用域或轮换机制时
references/CUSTOM_CREDENTIALS.md
需要在单个凭证中配置多头部/头部加查询参数认证,或需处理请求签名模式(HMAC、JWT、Webhook验证)时
references/HTTP_REQUEST_WITH_AUTH.md
为HTTP Request节点配置认证:Bearer、基础认证、OAuth、头部认证
references/FINDING_API_DOCS.md
用户提及了你不了解的服务时

Anti-patterns

反模式

Anti-patternWhat goes wrongFix
Pasting
sk-...
into HTTP Request's
Authorization
header value field
Token in plain text in the workflow JSON, leaks on export, copy, screenshotUse a credential:
Bearer Auth
for bearer tokens,
Header Auth
for other custom auth schemes
Storing token in a Set node and referencing via expressionSame problem, value lives in workflow JSONSame fix: credential, not a Set node
Using HTTP Request when a native node existsLoses auto-refresh on OAuth, loses native error handling, more codeUse the native node
Hardcoding credentials in SDK code (
new HttpRequest({ headers: { Authorization: 'Bearer xxx' } })
)
Same leak surfaceUse
newCredential()
in SDK code
Asking the user to create a credential without naming the credential typeUser picks the wrong type, auth fails confusinglyAlways specify: "create a credential of type
<exact type name>
"
反模式问题所在修复方案
sk-...
粘贴到HTTP Request节点的
Authorization
头部值字段
令牌以明文形式存在于工作流JSON中,导出、复制、截图时会泄露使用凭证:Bearer令牌用
Bearer Auth
,其他自定义认证方案用
Header Auth
将令牌存储在Set节点中并通过表达式引用同样的问题,值存储在工作流JSON中相同修复方案:使用凭证,而非Set节点
存在原生节点时仍使用HTTP Request节点失去OAuth自动刷新功能、原生错误处理,需要编写更多代码使用原生节点
在SDK代码中硬编码凭证(
new HttpRequest({ headers: { Authorization: 'Bearer xxx' } })
同样存在泄露风险在SDK代码中使用
newCredential()
让用户创建凭证但不指定凭证类型用户选错类型,导致认证失败且难以排查始终明确指定:“创建类型为
<准确类型名称>
的凭证”