[LW24] KeyHippo
p/lw24-keyhippo
Add API key auth to Postgres Row Level Security (RLS) policy
David Cox
KeyHippo [LW24] — Add API key auth to Postgres Row Level Security (RLS) policy
Featured
7
https://launchweek.dev/lw/MEGA KeyHippo is a Postgres extension that lets you issue API keys directly from SQL and validate them in RLS policy in parallel with your existing session-token flow (e.g. Supabase Auth).
Replies
Best
David Cox
Maker
📌
Hey Product Hunt! 👋 I'm David, founder of Integrated Reasoning. Today we're launching an open-source Postgres extension called KeyHippo! Integrated Reasoning started out as a hardware company, developing accelerators for optimization problems like the traveling salesman problem. In our search for product-market-fit we started launching SaaS products. After shipping a few projects built on Supabase, we accumulated a solid internal repository of SaaS code. One thing that was missing from this was a good solution to issuing API keys that work nicely with Supabase Auth and Postgres RLS. There are a handful of GitHub issues related to this problem, but Felix Zedén Yverås (FelixZY) puts it best: > Support API key generation (Supabase #12328) > > Please support generating user-tied API keys via supabase-js/GoTrue > I'm developing an open API. Users can sign into a web portal and generate API tokens to be used when communicating with the API. Users can generate multiple tokens, e.g. if they want to use different keys for Android and iOS client applications and track their usage separately. > > Currently, I can find no good way of generating such tokens/API keys without exposing secrets or breaking RLS. KeyHippo solves this problem well. We use it every day internally and it's use in production by Autarc (YC S24). By launching on Product Hunt we hope to: 1) Help other developers who face the problems that KeyHippo solves 2) Grow KeyHippo's developer community (thanks @tomasfrancisco for our first community PR!) I'll be launching a new feature every day this week as part of Mega Launch Week 2024 and will be around to answer any questions.
flo merian
@d4r5c2 neat product and perfect sync with Supabase's Launch Week 13 — keep up great work, David!
David Cox
Thanks @fmerian!
Huzaifa Shoukat
Congrats on the launch, @keyhippo! This looks like a game-changer for Postgres security. How do you see this impacting the developer experience compared to other methods of managing API keys?
David Cox
Thank you @ihuzaifashoukat!

 I see KeyHippo being most impactful to new projects that aim to grow quickly. I asked nearly 100 seed stage founders how they implemented API key issuance. About half said they generate a random UUID and store it in Postgres _unhashed_. This isn’t great from a security standpoint, and it’s also bad from a product standpoint as remediating it requires re-issuing keys to all of your customers. KeyHippo offers a faster and more secure alternative to this surprisingly costly corner cutting method. The second most common response was some form of key issuance independent from the database (e.g. AWS API Gateway) and an edge function to validate the key, retrieve it’s associated `user_id`, and perform Postgres requests using either the `anon` or `supervisor` Postgres roles. This approach is better, but it has a few downsides: - Using an intermediate edge function to validate keys negates much of the benefit of PostgREST — which is one of the best features of Supabase in terms of decreasing time to MVP. The extra hop also introduces latency, which can be problematic if your edge function, database, and user aren’t in the same region.
 - Supabase’s client library uses JWTs to manage sessions. If you’re building a web app and have server-side functions that use the client library, it’s not easy to re-use these functions in API routes if the key is validated outside of Postgres. With KeyHippo, you can create a Supabase client that includes the user’s API key in the authorization header like: ```ts const supabase = createClient( supabase.supabaseUrl, supabase.supabaseAnonKey, { global: { headers: { Authorization: apiKey } }, auth: { persistSession: false, detectSessionInUrl: false, autoRefreshToken: false, }, }, ); ``` The authorization header set by `createClient` is accessible within RLS, and KeyHippo includes a helper function that uses it to verify the key with a syntax that’s familiar to users of Supabase Auth. The third most common response I got from founders when asking about API keys is that they end up re-implementing much of their RLS policy logic in their edge functions. Not only is this duplicate work, it’s error prone and will only get more challenging to maintain as the project grows. It’s also extremely challenging to implement this sort of filtering for complex queries involving multiple joins / subqueries. The authors of Postgres did a great job with RLS — if you’re shipping a new app, I think it makes sense to lean on this amazing feature as much as possible. My hope is that KeyHippo will make the advantages of RLS accessible to more people at the earliest stages of their product's development.
Marius Seufzer
We already use KeyHippo at autarc, it’s a great product for sure!
David Cox
@marius_se thank you for supporting KeyHippo and for all of your outstanding feedback! Working with you and the rest of the autarc team is one of the highlights of my entire startup experience to date. Hacking together with you guys during the batch was such a blast. I admire that you took a chance on the product when it was only a few git commits old and am so excited for all that we'll build together as autarc grows