The Keyroute Project

A self-hosted AI gateway that keeps your API keys on your own Supabase project instead of someone else's server — built to solve my own key-juggling problem across side projects.

August 23, 2026

The Keyroute Project is a self-hosted AI gateway I built that gives you one URL for OpenAI, Groq, and Gemini — and it runs entirely inside your own Supabase project, so your API keys never sit on anyone else's server.

I kept running into the same annoyance across my side projects: a different API key and base URL hardcoded into every single one. Rotate one key, and now I'm hunting through four repos to fix it. Try a different provider for one project, and that's a code change, not a settings toggle. Plenty of hosted "AI gateway" products solve the routing part, but they all want your provider keys sitting on their servers — a real trust ask for something that can rack up real charges. So I built my own version where the whole thing runs on infrastructure you already control.

What it actually does

  • One URL, any provider — label a key "work" or "fast", call it as work/gpt-4o or fast/llama-3.3-70b, and it routes automatically. Only one key set up? Skip the label entirely.

  • Drop-in OpenAI compatibility — point any existing OpenAI SDK at it, swap in one key, everything else about your code stays the same, streaming included.

  • Keys encrypted at rest via Supabase Vault (AES-256) — the app layer never reads them back in plaintext after you paste them in.

  • Real usage logs — every request tracked by model, tokens, latency, and status, so you actually know what you're spending.

  • One-click self-hosting — paste a Supabase access token, click a button, done. No CLI commands.

The stack

React, TypeScript, and Vite for the dashboard. Supabase — Postgres, Auth, Vault, and Edge Functions on Deno — for literally everything else. That's the whole backend. No separate server to rent, no separate database to manage.

The biggest lesson: a valid login doesn't mean a read will work

I hit a bug that took way longer to track down than it should have. Everything would deploy fine, the silent owner account would sign in successfully, and then reading data back would fail with "permission denied" — even with a completely valid session.

Turns out in Postgres, a row-level security policy and a table-level grant are two separate things. You can have a perfectly correct security policy scoping rows to their owner, and still get blocked, because nobody actually granted basic SELECT access at the table level. RLS filters rows; it doesn't substitute for the grant. Once I found that gap and fixed it across every affected table, the whole thing worked end to end.

Getting a real one-click deploy button working was its own fight

The idea — click a button, get a fully provisioned gateway — is simple to say and genuinely annoying to build.

  1. Supabase's own API for provisioning a project doesn't allow calls directly from a browser, so the button needed a small proxy in front of it: a dev-server middleware when running locally, or an equivalent serverless function when the dashboard is deployed to Vercel. Same underlying logic, two different places it can run.

  2. The actual function-deploy step kept failing with "invalid multipart boundary" — turned out Supabase's deploy endpoint wants a real multipart form upload, not plain JSON.

  3. The auto-created "owner" account (so there's no login screen on a fresh self-hosted install) kept getting rejected with "invalid email address," because I'd made up a fake domain for it. Swapping it for example.com — an actual domain reserved specifically for placeholder use like this — fixed it.

On keeping this actually self-hosted, not just "self-hosted-ish"

It would've been easy to quietly lean on a proxy I host to work around the browser CORS problem above. I didn't want that — the whole point is that nobody's infrastructure but yours is in the loop. So the proxy runs on whatever you're already running the dashboard on — your own machine, or your own Vercel account — never on a shared service sitting in between.

Where to find it

The code is public: github.com/basavarajpatil660/the-keyroute-project

Full setup instructions are in the repo's SETUP.md, and it's MIT licensed — self-host it, fork it, change whatever you want.

More build logs and other projects are on basavaraj.dev.