I built a simple 2-node workflow that proxies OpenAI-compatible API requests to OpenRouter, keeping the API key off the calling machine. Sharing it in case others find it useful.
The problem: If you run local AI agents (LangChain, CrewAI, OpenClaw, etc.), the API key for your cloud LLM typically lives on the agent’s machine. If the agent is compromised via prompt
injection, that key can be exfiltrated.
The fix: Move the key to your n8n instance on a separate machine. The agent calls a webhook with a proxy token, n8n validates it and injects the real API key for the upstream call. The agent
never has the key — not on disk, not in memory.
Workflow: Webhook → HTTP Request. That’s it. The webhook validates a proxy auth token, the HTTP Request node forwards the body to OpenRouter with the real key. Uses responseMode: lastNode so the
upstream response passes straight back.
Tip: Create each credential from inside the node that uses it (not beforehand) — avoids confusion when both show as “Header Auth account” in the dropdown.
Works with any OpenAI-compatible API — just change the upstream URL.
GitHub (MIT licensed): GitHub - KeithBrodie/n8n-openrouter-proxy: n8n workflow that proxies OpenAI-compatible API requests to OpenRouter, keeping the API key off the AI agent host
3 „Gefällt mir“
Really like the framing here — “the upstream key should never sit on the agent machine” is exactly the right threat model to design against.
Wanted to share a related tool in case it’s useful to you or anyone else reading this thread: postagent — GitHub - actionbook/postagent: Let your AI agent connect to thousands of APIs. · GitHub . It’s a CLI built for AI agents, kind of like Postman but designed around the agent workflow. The overlap with your proxy:
- Credentials live in postagent’s local vault, not in env vars or code the agent can read.
- The agent only ever runs postagent send … The API key is injected into the outbound request at send time, so it never enters the model’s prompt context — prompt injection can’t get the model to print or exfiltrate a key it has never seen.
- Works with any HTTP API, including OpenAI-compatible endpoints (OpenRouter, etc.).
Where it’s a subset of what your n8n workflow does: postagent is a local CLI, so it defends against the “model leaks the key” class of attack, but not against a fully compromised host — an attacker with shell access on the agent machine can still read the vault. Your “key lives on a
different machine” topology gives a strictly stronger isolation boundary. So: for users who specifically want the separate-host guarantee, your workflow is the right answer; for users who just want to stop the prompt-injection exfiltration path without running a separate service,
postagent is lighter.
Would be great if you gave it a try — if you hit anything rough, or have feature requests (SSE streaming passthrough for chat completions, scope-bound credentials, etc.), open an issue on the repo and you’ll get the fastest turnaround directly from me.
I will take a look - thanks
welcome to the n8n community @KeithBrodie
Smart pattern. The main thing I’d add is rate limiting and audit logs on the webhook endpoint. If this becomes the gateway for multiple agents, tracking who called it, how often, and for which model can be just as valuable as hiding the API key, especially for abuse prevention, debugging, and cost visibility.
This is a useful pattern for local agents. I would add one more layer to the proxy idea: don’t only hide the upstream key, also make the token that the agent uses scoped and quota-capped.
For agent workflows, I usually want:
```text
agent token: separate from the upstream provider key
quota: hard cap for that agent/task
logs: request id, model, prompt/completion tokens
base_url: explicit OpenAI-compatible /v1 endpoint
```
That way a local agent loop cannot quietly drain the real provider key, and you can still see which workflow/model burned the tokens.
I wrote the setup checklist here: GitHub - alicekellings/cursor-cline-token-budget: Practical token budgeting and usage transparency setup for OpenAI-compatible coding agents. · GitHub
Disclosure: I maintain Wappkit (https://api.wappkit.com), an OpenAI-compatible gateway with quotas and usage logs. Same idea applies if you build the proxy directly in n8n.
Good pattern. The key-custody part is the first thing to get right: the local agent should only see a proxy token, not the upstream OpenRouter/OpenAI key.
If this grows from a two-node proxy into a reusable OpenAI-compatible gateway, I would also keep the accounting side explicit: requested model, resolved upstream provider/model, workflow or user key, input/output/cached tokens when available, retry/failure state, and final debit. That is the direction we are taking with Tokens Forge as an API relay plus wallet/usage receipts, so users can debug both security and spend without exposing upstream keys.
The proxy pattern solves the key custody problem well. One more layer worth adding, especially if this runs multi-tenant: per-request client attribution so you know which downstream consumer drove each token spend.
The simplest form: the calling agent attaches a custom header (something like X-Client-ID) when it hits the proxy webhook. The proxy captures that header before forwarding to OpenRouter. When you pull the audit log, you can see not just “100k tokens this week” but “client A: 60k, client B: 30k, runaway workflow C: 10k.” That distinction matters when you bill clients or when one workflow starts hammering the proxy harder than expected.
Without attribution, the first signal of a runaway workflow is hitting your monthly OpenRouter cap. With it, you catch the outlier while the other clients’ workflows keep running cleanly. The header approach is lightweight – one Set node on the calling side, one read step in the proxy before the forward.
1 „Gefällt mir“