n8n-credentials-and-security
n8n Credentials and Security
Non-negotiables
- 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'scredentialsparameter. A Set node hardcoding a token and read via{{$json.token}}is a text field with extra steps. - 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. - 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".
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
httpCustomAuthcredential type. Seereferences/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.
More from n8n-io/skills
n8n-loops
Use when working with multi-item data, batches, paginated APIs, rate-limited APIs, anything that needs to "do this for each", or any time the user mentions looping, iterating, batching, paging, or "loop over items". Triggers on "loop", "iterate", "for each", "batch", "page through", "paginate", "rate limit", "process all", or any node that should run once vs once-per-item.
5n8n-connections
Use when writing or reviewing n8n SDK code that wires IF, Switch, Merge, error outputs, or any multi-input/multi-output connection. Triggers on .add(), .to(), .input(n), .output(n), .onTrue, .onFalse, .onCase, .onError, useDataOfInput, merge, switch, IF nodes, error branches, fan-out, fan-in, or any review of the workflow's connections object.
3n8n-expressions
Use when writing or reviewing n8n expressions (`{{...}}` syntax), `$json` / `$node` references, Luxon date code, or expression errors. Triggers on `{{}}`, `$json`, `$node`, `$input`, `DateTime`, `Luxon`, "expression error", "evaluating", "format date", "transform field", or any node-parameter assignment.
3n8n-debugging
Use when an n8n workflow isn't working, errors appear, results don't match what was expected, or the user says "this isn't working." Triggers on errors, unexpected output, "it's not working", "why is this happening", "the workflow stopped", failure investigation, or any debugging context.
3n8n-code-nodes
Use when the user reaches for a Code node, mentions writing JavaScript or Python in n8n, or any custom logic comes up in workflow design. Triggers on "Code node", "Code", "JavaScript", "Python", "custom logic", "transform data", "$input", "$json transformation", "loop in code", "write a function", or any time the obvious answer seems to be "just put it in code.
3n8n-data-tables
Use when working with n8n's built-in Data Tables, designing schemas, inserting/updating/upserting rows, deduping, or querying. Triggers on "Data Table", "data table", `n8n-nodes-base.dataTable`, "dedup", "idempotency", "lookup", "persistent state", "store across executions", or any schema design discussion inside n8n.
3