Encrypt OAuth Tokens in Supabase Without an RLS Leak (Simply Explained)
A plain-language guide to encrypt oauth tokens supabase. No jargon, no tech speak, just what it means for your business.
By Mike Hodgen
I Was Holding the Keys to a Law Firm's Entire Case Load
I built an AI system for a law firm that plugs straight into their case management software. It reads case files, drafts updates, files documents, keeps everything in sync. Real work that saves real hours.
To do any of that, my system has to hold the firm's login credentials for their case system. Think of it like a master key to the building.
Sit with that for a second. If those keys leaked, someone could read or change every case in the firm. Private client conversations. Settlement numbers. All of it.
Here is the thing most people miss. When you let an outside company connect to your systems, you are not just trusting their AI. You are trusting how they store your keys. And most get it wrong without ever knowing, because the wrong setup looks perfectly fine in a demo.
The Mistake That Looks Like It Works
The obvious way to store a client's keys is to put everything in one filing cabinet. One drawer per firm. In that drawer you keep the boring status stuff (are we connected, when did we last sync) right next to the actual keys.
Then you put a lock on each drawer so each firm can only open its own. Done, right?
Not even close. Here is the problem.
The app needs to show the firm's staff a little green "Connected" badge and a "last synced 4 minutes ago" note. So you give the staff permission to open their own drawer and read that status.
But the keys are in the same drawer. The moment you let a junior paralegal open the drawer to check the status, you have also handed them the master keys sitting right next to it.
"But the keys are encrypted." Sure. Now every employee has a locked safe and all the time in the world to crack it at home, with nobody watching. Encryption is not the fix here. The way you organized the filing cabinet is.
The Fix: Two Cabinets, Not One
The solution is almost embarrassingly simple once you see it. Stop putting two completely different kinds of information in the same place.
I use two separate cabinets.
The first cabinet holds only the harmless stuff. Are we connected. When did we last sync. Any error messages worth showing. The firm's staff can open this one freely, because there is nothing in it worth stealing. That green "Connected" badge works perfectly.
The second cabinet holds the actual keys. And here is the move that makes the whole thing work: I put a lock on it with no key. Nobody on the staff side can open it. Not their own. Not anyone's. There is literally no way in through the front door.
The only thing that can open the second cabinet is my server, the trusted machine running behind the scenes. It never hands that ability to a web browser, never puts it in front of a user, never shows up in anything a person could poke at.
So the staff can see their status all day long. And the keys sit behind a wall with no door for anyone but my server. I did not write some clever permission rule. I removed the permission entirely.
Belt and Suspenders, Because I'm Holding Their Keys
The key cabinet is already unreachable. So why bother locking the keys themselves inside it?
Because when you hold someone else's master keys, you assume something will eventually go wrong. A backup gets misplaced. A future engineer makes a careless change. I design so that even if someone walks off with the whole cabinet, the keys inside are still useless.
I do two things.
First, I weld each key to the exact firm and exact system it belongs to. If a thief grabs Firm A's key and tries to use it in Firm B's account, it simply does not work. The key only functions in the one place it was created. You cannot move it, copy it, or reuse it somewhere else.
Second, I tag every key with a version number. That means I can swap out my master encryption whenever I want without a scary all-at-once overhaul. Old keys and new keys live side by side and update naturally over time. Zero downtime.
The Mistake I Caught in My Own Work
Here is the part where I tell on myself, because finding your own mistakes is the whole job.
Halfway through building this, I went back and audited the connection process. And I found something ugly. The raw keys were being stored in plain text in the user's browser, set to stick around for 30 days.
Read that again. I had built a vault with no door, welded the keys to each firm, the works. And meanwhile the actual key was riding around in the open, in the browser, for a month. Every protection I just described was pointless, because the key never needed to be attacked in the vault. It was sitting out in the parking lot.
The fix was simple once I saw it. The keys never leave my server now. The browser only holds a meaningless ticket stub that only my server can read. The real key stays locked away.
I also closed a second door. When something fails, the natural reflex is to write down the error so you can see what went wrong. But error messages sometimes contain the very key that just failed. So I scrub out anything sensitive automatically before it ever gets written down. A failure can never accidentally spill a key into a note someone could read.
I catch these because I assume I made them. That is the difference.
Proof, Not Promises
A claim that the keys are locked down is worth nothing if I cannot prove it. So I wrote an automatic test that tries to break in.
The test pretends to be a normal staff member, then attacks. It tries every sneaky way I can think of to reach the key cabinet. It only passes if every single attempt gets denied. If even one works, the whole thing stops cold before it ever goes live.
And it runs every time we update the software, not just once. So if some future change accidentally opens that cabinet, the alarm goes off before it reaches a single real customer.
That is the difference between a company saying "your keys are safe" and a company showing you a test that turns red the instant they're not.
What to Ask Anyone Holding Your Keys
When an AI system connects to your case software, your customer records, your bank feed, it is holding keys that could do real damage. That is the deal you make every time you connect an outside tool.
So do not ask "do you encrypt." Everyone says yes, and as I just showed you, encryption alone does not even close the leak.
Ask three sharper questions. Can anyone but your server reach the keys. Does your design assume mistakes will happen. Can you prove it with a test. Most companies cannot answer all three, and many have never even thought about the first one because their sloppy setup demos perfectly.
I build this protection in from the very first day, not bolted on after something goes wrong. And I am the person who builds these systems, not just someone who talks about them from a slide.
Want to explore what AI could do for your business?
Book a free 30-minute strategy call. No pitch deck, no sales team, just a real conversation about your operations and where AI fits.
Get AI insights for business leaders
Practical AI strategy from someone who built the systems — not just studied them. No spam, no fluff.
Ready to automate your growth?
Book a free 30-minute strategy call with Hodgen.AI.
Book a Strategy Call