关于 n8n-credentials-and-security
为 n8n 工作流和 SDK 代码配置凭据提供安全指南,说明如何绑定现有凭据并避免秘密出现在工作流文本中,同时明确凭据需由用户在 UI 中创建。
主要功能
- 01凭据选择与 ID 绑定指南
- 02避免秘密进入工作流字段的规则
- 03原生认证与 HTTP 认证方式选择
- 04处理用户在聊天中粘贴秘密的步骤
适用场景
- 01为 n8n 节点配置身份验证
- 02为外部 API 选择认证方式
- 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.mdCUSTOM_CREDENTIALS.mdFINDING_API_DOCS.mdHTTP_REQUEST_WITH_AUTH.md详细介绍
n8n 凭据与安全
不可妥协的原则
- 通过凭据系统管理密钥,绝不放在文本字段或 SDK 代码中。 API 密钥、Bearer 令牌、OAuth 密钥、密码:全部通过
newCredential()或节点的credentials参数处理。在 Set 节点中硬编码令牌,再通过{{$json.token}}读取,只不过是多绕了几步的文本字段。 - 先列出凭据,再按 ID 绑定。 配置需要身份验证的节点之前,先调用
list_credentials({type})。只有一个匹配项:创建时通过双参数newCredential('Label', 'credId')绑定,或在update_workflow上使用setNodeCredential操作。多个匹配项:询问用户要用哪一个。单参数newCredential('Label')只是一个占位符;n8n 会自动分配该类型最近编辑的凭据,如果用户有多个凭据,就可能悄无声息地选错。 - 凭据应由用户创建,而不是由你创建。 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”
处理方式:
- 不要将令牌放进文本字段,即使只是暂时放入也不行。 在 Set 节点中硬编码该值,再通过
{{$json.token}}引用,只不过是多绕了几步的文本字段。 - 尽可能绑定到现有凭据。 先调用
list_credentials({type});如果有匹配项,通过setNodeCredential绑定,并告知用户你使用了哪一个。如果没有匹配项,告诉用户在 UI 中创建凭据(Bearer 令牌使用 Bearer Auth,自定义标头使用 Header Auth 等)。凭据仍只能通过 UI 创建。 - 将粘贴的密钥视为已泄露,并告知用户轮换密钥。 不要淡化此事。该令牌已传输给 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