GUIDE

Supabase anon vs service_role: the two-key rule

Every Supabase project has two main keys, and confusing them causes both kinds of grief: panic over a key that's fine, and calm about a key that's a five-alarm fire.

The two keys

keymeant to bewhat it can do
anonpublic; it ships in your app on purposeonly what your database rules allow that user to do; the rules are the security, not the key's secrecy
service_rolesecret; server-side only, never in the browsereverything, ignoring every rule: read any table, delete anything, all users' data

How to check which one your app is showing

Both keys look like long eyJ... strings, but each carries its own label inside. View your live site's source, copy any eyJ... key you find, and ask your AI:

This is a Supabase key from my app. Decode it (it's a JWT; the middle section is base64) and tell me the value of its "role" claim. If the role is "anon" tell me it's fine. If the role is "service_role" tell me clearly that it must be rotated.

Role anon: relax: that key in the page is how Supabase is supposed to work. Role service_role: treat it as leaked and follow the emergency steps: rotate in Supabase first, then get it out of the app.

The part the anon key's safety depends on

"Anon is fine to expose" is true only while your database rules (row-level security) are actually restricting what it can reach. An exposed anon key plus missing rules means anyone can read your tables, not because the key leaked, but because the door it opens was never locked. The two-account test in the security checklist verifies this in ten minutes; run it once per launch.

Plyo is the home for AI-built projects — every version saved, one click to undo, one click to publish, plus a safety check, visitor counts and backups. Free to start: 3 projects, no card needed.

Give your project a home