mcpField
N
n8n-credentials-and-security-official

n8n-credentials-and-security-official

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

关于 n8n-credentials-and-security-official

为使用 n8n 的 Agent 提供凭据与安全配置规范,指导如何将外部服务认证绑定到工作流节点。重点是通过凭据系统管理密钥,并避免在聊天、文本字段或代码中暴露秘密。

主要功能

  1. 01使用凭据系统存储秘密
  2. 02先列出凭据再按 ID 绑定
  3. 03优先选择原生凭据类型
  4. 04为自定义认证选择合适类型
  5. 05处理聊天中粘贴的秘密

适用场景

  1. 01为工作流节点配置外部服务认证
  2. 02安全设置 HTTP Request 身份验证
  3. 03发现密钥泄露后指导轮换

安装

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

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

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

包含的文件

除 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