I've been building an open-source project called Keyroute, a self-hosted AI API gateway that lets you use one API key to route requests to multiple providers (OpenAI, Gemini, Groq, etc) instead of juggling separate keys and separate integration code for each one.

The whole point of it is that it runs entirely inside YOUR own Supabase project, not on any server of mine. No relay, no third party sitting between you and your AI provider. Setup is one button, no CLI needed.
Getting there wasn't smooth. Here are three bugs that each ate a full day, in case any of these save someone else the same pain.
Bug 1: "Invalid multipart boundary"
The Deploy Gateway button needs to actually deploy a Supabase Edge Function programmatically, through Supabase's Management API, from the browser.
My first attempt sent JSON, since that's what basically every other API expects these days. Kept getting rejected with an "Invalid multipart boundary" error that told me nothing useful.
Turns out the function-deploy endpoint needs real multipart/form-data: the slug goes as a query param, there's a metadata part as a JSON string, and then one separate file part per source file. Not obvious at all from the error message, took a lot of trial and error against a real project to get the exact shape right.
Bug 2: the email domain nobody warns you about
Since Keyroute has no login/signup flow (there's a single auto-provisioned owner account created during setup), I needed to generate a synthetic email for that account behind the scenes.
First attempt: owner@local.keyroute. Rejected by Supabase Auth as invalid.
Second attempt: I switched to my own real domain, @local.basavaraj.dev. This worked, but it bugged me, since it meant every single person who self-hosts this project would have my personal domain baked into their database. Not a good look for an open source project other people are supposed to run themselves.
Ended up landing on @example.com, which is an actual RFC 2606 reserved placeholder domain, made exactly for situations like this. Verified it against real Supabase Auth and it worked cleanly. Small fix, but the kind of thing that's easy to get wrong in a way that quietly ships something awkward.
Bug 3: RLS was right, but reads still failed
This one really got me. I had Row Level Security policies set up correctly on four tables. Tested with a real, valid, logged-in session. Reads still failed.
Spent a long time assuming this was a session or auth token issue, since that's usually what "valid session but no data" means.
It wasn't. In Postgres, RLS policies and table-level GRANTs are two completely separate permission systems. You can have perfect RLS policies and still block every request if the authenticated role was never explicitly granted access to the table itself. I'd done the policies and just... never done the grants.
Once I ran the GRANT statements, everything worked instantly. Felt a little silly after how long I spent debugging it as an auth problem.
Bonus lesson: don't trust "commit succeeded" from an AI coding tool
Not a code bug, but worth mentioning since it almost caused a real problem. I'm using an AI coding assistant to help implement changes, and at one point it reported "committed and pushed successfully" when in reality only git add had run, no commit ever happened.
I only caught it because I checked GitHub directly and saw nothing new there. Now I always verify against raw git log / git status output myself instead of trusting a prose summary, especially for anything commit or push related.
Where it's at now
Keyroute is open source, MIT licensed, and self-hostable. Still has some gaps (no Anthropic routing yet, no rate limiting yet, single-owner model for now), but the core flow works end to end.
Repo: github.com/basavarajpatil660/the-keyroute-project
If you've hit similar Supabase Edge Function or RLS quirks, or have thoughts on the architecture, I'd genuinely like to hear about it.
Top comments (0)