As an indie developer who runs wallpaper apps, I once sat with the Supabase dashboard open, half-way through typing "Connect Supabase" into Rork's chat box, and stopped. The screen showed several keys in a row, and I could not tell which one was meant.
Rork's own docs keep the steps short. Create a new project in Supabase, copy the Publishable key and the project link, then paste both into the chat along with "Connect Supabase." That's all. The "copy" part is left to screenshots, though, so the page never says in words which string it means.
What follows is the preparation I'd do before pasting. Two values are safe to paste, and one is not. Knowing that in advance means you won't have to decide in the second before you hit enter.
You only need two values
Rork's docs ask for these:
| Value | What it looks like | Safe to paste? |
|---|---|---|
| Project URL (the docs call it the project link) | An address shaped like (letters and digits).supabase.co | Yes |
| Publishable key | starts with sb_publishable_ | Yes |
| Secret key | starts with sb_secret_ | No |
According to Supabase's documentation, the Publishable key is a low-privilege key that is "safe to expose online" in web pages, mobile apps, and source code. It is built on the assumption that Row Level Security decides what it can read and write.
The Secret key is a different animal. The same docs say it bypasses every Row Level Security policy you have, so it belongs only in backend code you control, such as servers or Edge Functions. It should never end up in a shipped app or in source control.
Rork's page says nothing about the Secret key at all. I read that as a reason to draw the line myself, rather than assuming silence means safety.
Where to copy them from
There are two places to look.
If you want the URL and the key side by side, use the Connect dialog in the Supabase dashboard. It shows the URL and the Publishable key for the framework you pick.
If you only need the key again, go to Settings > API Keys. Every key lives there, including the legacy ones. Look for the row named "Publishable key." A "Secret key" row usually sits right beside it, so I trace the row name with my finger before copying.
Legacy keys may still be on screen: anon (the old form of the Publishable key) and service_role (the old form of the Secret key). Both are long strings starting with eyJ, so you can't tell them apart by eye. Supabase says it plans to deprecate them by the end of 2026, and creating the new keys does not disable the old ones. They stay valid until you turn them off in Settings > API Keys.
Check the shape before you paste
Because the legacy keys look identical, I let a script look for three seconds before I paste. It checks the URL's shape and the key type. For a legacy key it decodes the JWT payload and reads role, so it can tell anon from service_role.
It solves one narrow problem: mixing the values up at the last moment. It makes no network calls and only inspects the strings you hand it.
// check-supabase-values.mjs
// Checks locally whether your two values are safe to paste.
// Usage: node check-supabase-values.mjs "<Project URL>" "<key>"
const [url = "", key = ""] = process.argv.slice(2);
const problems = [];
// 1) Project URL: must look like https://<project-ref>.supabase.co
if (!/^https:\/\/[a-z0-9]+\.supabase\.co\/?$/.test(url.trim())) {
problems.push("URL is not in the https://xxxx.supabase.co form (check for a trailing /rest/v1)");
}
// 2) Tell the key types apart
const k = key.trim();
if (k.startsWith("sb_publishable_")) {
// safe to paste
} else if (k.startsWith("sb_secret_")) {
problems.push("This key starts with sb_secret_. It must never go into the app");
} else if (k.startsWith("eyJ")) {
// Legacy JWT: read the role inside to tell anon from service_role
try {
const payload = JSON.parse(Buffer.from(k.split(".")[1], "base64url").toString());
if (payload.role === "service_role") {
problems.push("This is a legacy service_role key. It must never go into the app");
} else if (payload.role !== "anon") {
problems.push(`Unexpected role=${payload.role}. Look for the Publishable key again`);
}
} catch {
problems.push("Starts with eyJ but cannot be read as a key. Check that the copy was not cut off");
}
} else {
problems.push("Unknown key format. Copy the Publishable key again from Settings > API Keys");
}
if (problems.length) {
console.log("Stop before pasting:\n- " + problems.join("\n- "));
process.exit(1);
}
console.log("OK: this is a Project URL and a Publishable key. Safe to paste.");I ran it on Node 22 with dummy strings. A sb_publishable_ key passes. A sb_secret_ key and a legacy key whose role is service_role both stop with exit code 1. So does a URL with /rest/v1 tacked on the end.
The reason it checks the URL shape is that the longer API address shown elsewhere is easy to copy by mistake. What you paste is the short form, from https:// through .supabase.co.
The paste itself
When the values are ready, paste them into your Rork project's chat in one message, as the docs describe.
Connect Supabase
Project URL: https://(your-project).supabase.co
Publishable key: sb_publishable_(the string you copied)After that, follow the setup instructions Rork gives you in the chat. From here Rork's reply leads, and I have little to add.
One more thing: if the backend runs under your own Supabase account, Supabase bills you directly. The docs also point to a Rork-hosted option. Deciding who sends the bill up front saves a surprise later.
If it doesn't connect
When data won't load after pasting, I'd suspect Row Level Security before the key. The Publishable key is low-privilege by design, so with no policies in place, getting nothing back is the correct behavior. I've written the troubleshooting order in Supabase data not showing in a Rork app.
Where to keep keys for other external APIs is a separate question from the Supabase keys. See environment variables versus a Supabase Edge Function, along with the runbook for rotating a key that crossed the client boundary.
And if you realize you pasted a Secret key, rotate it in Settings > API Keys. A value that has once entered a chat or generated code can't be un-pasted just by deleting it.
Paste only the two values meant to be public; when in doubt, stop. I repeat that sentence to myself every time I handle keys.
Your next step is a small one: find the Publishable key row in Supabase, run it through the script above, and then paste.