mcpField
N
n8n-credentials-and-security

n8n-credentials-and-security

github.com/n8n-io安全558345 次安装2 周前更新
代码仓库

关于 n8n-credentials-and-security

为 n8n 工作流和 SDK 代码配置凭据提供安全指南,说明如何绑定现有凭据并避免秘密出现在工作流文本中,同时明确凭据需由用户在 UI 中创建。

主要功能

  1. 01凭据选择与 ID 绑定指南
  2. 02避免秘密进入工作流字段的规则
  3. 03原生认证与 HTTP 认证方式选择
  4. 04处理用户在聊天中粘贴秘密的步骤

适用场景

  1. 01为 n8n 节点配置身份验证
  2. 02为外部 API 选择认证方式
  3. 03用户分享 API 令牌时采取应对措施

MCP 相关

README 提到 n8n MCP 不提供创建凭据的功能。该技能建议先列出现有凭据并绑定到节点;凭据由用户在 UI 中创建。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/n8n-io/skills --skill n8n-credentials-and-security

安装后在 Claude Code 中输入/n8n-credentials-and-security确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
CREDENTIAL_SYSTEM.md
CUSTOM_CREDENTIALS.md
FINDING_API_DOCS.md
HTTP_REQUEST_WITH_AUTH.md

详细介绍

n8n 凭据与安全

不可妥协的原则

  1. 通过凭据系统管理密钥,绝不放在文本字段或 SDK 代码中。 API 密钥、Bearer 令牌、OAuth 密钥、密码:全部通过 newCredential() 或节点的 credentials 参数处理。在 Set 节点中硬编码令牌,再通过 {{$json.token}} 读取,只不过是多绕了几步的文本字段。
  2. 先列出凭据,再按 ID 绑定。 配置需要身份验证的节点之前,先调用 list_credentials({type})。只有一个匹配项:创建时通过双参数 newCredential('Label', 'credId') 绑定,或在 update_workflow 上使用 setNodeCredential 操作。多个匹配项:询问用户要用哪一个。单参数 newCredential('Label') 只是一个占位符;n8n 会自动分配该类型最近编辑的凭据,如果用户有多个凭据,就可能悄无声息地选错。
  3. 凭据应由用户创建,而不是由你创建。 n8n MCP 不提供创建凭据的功能。告诉用户应在 UI 中创建的确切凭据类型,然后在节点配置中按标签引用。不要尝试以编程方式创建凭据,也不要接受用户在聊天中提供的密钥,打算“稍后再设置”。

强烈建议的默认做法

  • 有原生凭据可用时,优先使用。 每个原生节点(Slack、Gmail、Postgres、OpenAI 等)都有对应的凭据类型。存在原生选项时,不要使用通用凭据类型。
  • 对于多标头或标头加查询参数的身份验证形式,使用 httpCustomAuth 凭据类型。参见 references/CUSTOM_CREDENTIALS.md。

凭据系统

在 n8n 中,凭据是一等对象:

  • 在 n8n 数据库中静态加密存储。
  • 需要凭据的节点通过 ID 引用。
  • 按项目设定范围(Cloud 和企业版),或全局共享(某些可自托管的部署)。
  • 通过类型标识符(googleSheetsOAuth2Api、slackApi、httpHeaderAuth)识别。节点会引用此标识符,它也决定凭据需要收集哪些身份验证字段。

需要身份验证的节点有一个 credentials 参数,指向凭据 ID 和类型。密钥值绝不会出现在工作流 JSON 中。导出工作流泄露的是引用,而不是密钥。

完整模型(SDK 解析、轮换、项目范围设定)请参见 references/CREDENTIAL_SYSTEM.md。

身份验证方式决策树

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

用户在聊天中粘贴密钥时

这种情况确实会发生。用户会输入类似这样的内容:

“设置一个工作流,用 Bearer sk-abc123def456 调用 Acme API”

处理方式:

  1. 不要将令牌放进文本字段,即使只是暂时放入也不行。 在 Set 节点中硬编码该值,再通过 {{$json.token}} 引用,只不过是多绕了几步的文本字段。
  2. 尽可能绑定到现有凭据。 先调用 list_credentials({type});如果有匹配项,通过 setNodeCredential 绑定,并告知用户你使用了哪一个。如果没有匹配项,告诉用户在 UI 中创建凭据(Bearer 令牌使用 Bearer Auth,自定义标头使用 Header Auth 等)。凭据仍只能通过 UI 创建。
  3. 将粘贴的密钥视为已泄露,并告知用户轮换密钥。 不要淡化此事。该令牌已传输给 LLM 提供商,可能会保留在聊天记录、转录内容和缓存层中。告诉用户:“设置好新凭据后,请立即轮换此令牌。请将其视为已泄露。”

没有原生节点时

常见情况是用户想要连接 n8n 没有对应节点的服务。此时使用带有适当身份验证的 HTTP Request。

  • references/FINDING_API_DOCS.md:查找身份验证方式、基础 URL 和常见形式。
  • references/HTTP_REQUEST_WITH_AUTH.md:将 HTTP Request 连接到凭据。
  • references/CUSTOM_CREDENTIALS.md:内置身份验证类型不适用时参见此文档。

参考文件

文件何时阅读
references/CREDENTIAL_SYSTEM.md需要了解凭据的存储、引用、作用域或轮换方式时
references/CUSTOM_CREDENTIALS.md需要在一个凭据中配置多个请求头/请求头加查询参数身份验证,或配置按请求签名模式(HMAC、JWT、Webhook 验证)时
references/HTTP_REQUEST_WITH_AUTH.md配置带身份验证的 HTTP Request 时:Bearer、Basic、OAuth、Header Auth
references/FINDING_API_DOCS.md用户提到了你不熟悉其节点级知识的服务时

反模式

反模式问题所在修复方法
将 sk-... 粘贴到 HTTP Request 的 Authorization 请求头值字段中工作流 JSON 中会以明文形式存储令牌,导出或复制时会泄露,截图也可能暴露令牌使用凭据:Bearer 令牌使用 Bearer Auth,其他自定义身份验证方案使用 Header Auth
将令牌存储在 Set 节点中,并通过表达式引用同样存在上述问题,值会保存在工作流 JSON 中使用凭据,而不是 Set 节点
将机密存储在 $vars.X 中,并将其作为身份验证值读取静态存储时未加密,会在导出时泄露,且无法轮换使用合适的凭据类型(httpBearerAuth、httpHeaderAuth、httpCustomAuth 或原生凭据)。对于入站 Webhook 身份验证,请使用触发器的 authentication 字段,不要通过 IF 检查 $vars.token
在设置自定义身份验证时尝试使用 $env.X 读取机密无法正常工作,会在运行时抛出错误使用适当类型的凭据
存在原生节点时仍使用 HTTP Request会失去 OAuth 自动刷新功能和原生错误处理,还会增加代码量使用原生节点
在 SDK 代码中对凭据进行硬编码(new HttpRequest({ headers: { Authorization: 'Bearer xxx' } }))同样存在泄露风险在 SDK 代码中使用 newCredential()
要求用户创建凭据,却不说明凭据的类型用户可能选错类型,导致身份验证失败且难以排查始终明确说明:“创建类型为 <exact type name> 的凭据”

评论

支持 Markdown