I was about to share an n8n workflow and almost leaked an API key with it
An auth token was sitting in plain text inside an HTTP Request body. The security checklist I now run before releasing any workflow.
summary
Before exporting one of my workflows to share with the community, I opened the JSON and found an auth token pasted directly into an HTTP Request node’s body, in plain text — never routed through n8n’s credential system. Whoever downloaded that workflow would have gotten access to my API account along with it. I put together a two-part checklist (plaintext credentials, trigger security) to run before sharing or selling any workflow from now on.
Send the link to Claude
Opens a new Claude.ai chat with this post's link already in it — it reads the article, summarizes the key points, and you can keep asking questions there.
Before exporting one of my workflows to share with the community, I opened the JSON to take a general look at what was about to go out. One of the nodes was an HTTP Request calling an external API. The auth token wasn’t stored in an n8n credential — it was pasted straight into the request body, one of the fields the node sends, plain text sitting in the middle of the exported workflow.
Most people export and send without opening the file first — to post it in a forum, share it in a group, or sell it. Had I done that, whoever downloaded the workflow would have gotten access to my API account with it. I didn’t catch it because n8n warned me. I caught it because I opened the JSON with the specific intent of checking before releasing it.
Why the credential node doesn’t solve this on its own
n8n has a credential system built exactly for this — you register the key once, the node references it by name, the value never shows up in the exported JSON. It works well when you actually use it. The problem is the shortcut: for an API you’re only calling once, or a request you threw together while testing, it’s faster to paste the token straight into a body field than to register a new credential. That makes sense while the workflow is still just yours. It turns into a leak the day it leaves your account.
And it doesn’t show up from a visual review of the canvas. The body field displays the filled-in value the same way it would show any other payload data. It only becomes obvious once you open the JSON and read the raw parameter, because nothing in the UI signals that this particular field is a credential and not just regular request data.
The checklist I run now
Before sharing or selling a workflow, two security passes:
- 1.Plaintext credentials. Scan every HTTP/webhook/code node for an auth value pasted directly in — header, query param, body field — instead of a reference to a registered credential. Each hit becomes a decision: should this key actually be here, or should the node use a native credential with a placeholder in its place? I don’t leave this one to manual review: I built a tool that takes the pasted JSON and scans it for known credential patterns (Bearer tokens, OpenAI/AWS/Stripe/GitHub key prefixes, database connection strings) instead of relying on me remembering to open the file before exporting, which is exactly what almost didn’t happen this time. It matches on the shape of the value, not a guess: a generic token with no recognizable prefix can still slip through, so the scan cuts down the manual review work, it doesn’t replace opening the JSON every so often.
- 2.Trigger security. If the workflow exposes a webhook, it inherits whatever is — or isn’t — configured on it: required auth, rate limiting, payload shape validation. A workflow that runs fine on my account because I’m the only one calling the webhook can be completely open to whoever else finds the URL. This one still has to be manual: it depends on the trigger type and on what the destination instance already has set up, not something you can infer just by reading the JSON.
Outside the security scope but at the same review moment before releasing a workflow: writing down whatever is implicit to my own setup — a specific environment variable, an API version, a payload shape that only exists in my environment. Without that written somewhere, whoever buys it gets a workflow that breaks silently outside my environment and reads that as a quality bug, not a missing-context problem. That’s not a leak, it’s disappointment. But both come from the same habit of never having reviewed the workflow through anyone else’s eyes but mine.
What actually matters
Sharing or selling an n8n workflow means publishing a JSON that carries everything you pasted into it while building alone, with no audience watching. n8n’s credential system only protects what actually goes through it — it won’t warn you about the shortcut you took on a test call and forgot to clean up. Reviewing before releasing isn’t excessive caution, it’s the only step standing between “works on my account” and “leaked to whoever bought it”.
Questions
Leia também
Comments
- No comments yet.