u/AzureSu

Stopped n8n from holding real API credentials entirely — proxy boundary pattern (Lark + OpenAI, finance workflow)

Been running invoice OCR + Lark approval automation on n8n for a few months. The workflow itself works fine, but credential hygiene was a mess. Finally solved it structurally — sharing the pattern.

The core problem: Export workflow JSON → real sk-proj-... and Lark tenant_access_token travel with it. Hand it to a teammate, put it in version control, or give it to an AI coding tool — credentials leak. Even without hardcoding, the "fetch token first" node pattern means re-running any branch in isolation breaks the chain.

How the pattern works

1. Register each API as a named service in a proxy layer

  • Real credentials loaded from local env at registration time
  • Proxy holds them — n8n never sees them

2. Replace every direct API call in n8n with a proxy URL

  • https://<proxy>/s/api-lark-bot/open-apis/... instead of calling Lark directly
  • https://<proxy>/s/openai/v1/chat/completions instead of OpenAI directly

3. Store the proxy token as an n8n Header Auth Credential

  • Workflow JSON only carries credential id, never the real token
  • One rotating token for all downstream APIs

4. Delete the get-lark-token prefetch node

  • Token refresh happens inside the proxy layer
  • n8n doesn't know or care about Lark's 2h TTL

5. Grep before every commit

  • Two-layer check: redaction script + grep scan for known prefixes (sk-, cli_, Bearer )
  • Catches the case where someone pastes a token directly into a node header

What was harder than expected

  • The proxy token itself can still leak into JSON if you forget to use n8n's Credential store and paste it directly into a header — same problem, one layer up
  • Lark's tenant_access_token refresh timing: if the proxy caches the token and it expires mid-workflow, you get a 99991663 error. An IF node that retries once is enough
  • PDF → GPT-4o Vision requires image conversion first — pdf-to-png isn't in n8n's default Code node sandbox, need NODE_FUNCTION_ALLOW_EXTERNAL=pdf-to-png
  • Getting the proxy URL format right for path-auth APIs (Lark's endpoint structure is not RESTful in the obvious way)

What I like about this setup

  • AI tools can read and edit workflow JSON safely — no credentials to leak
  • Month-end audit is one place: proxy call log, not Lark + OpenAI + n8n stitched by hand
  • Token rotation happens once at the proxy, not across every workflow that uses the API
  • ~3 hours/week recovered on the finance side (teammate no longer forwards me invoices to type in manually)

Workflow (for anyone curious)

Four key nodes: Form Trigger (invoice upload) → GPT-4o OCR via proxy → human review step → Create Lark Approval via proxy.

Happy to share specifics on any node if useful.

reddit.com
u/AzureSu — 21 hours ago