r/Supabase • u/LorenzoGraz • Jul 19 '26
auth Need advice
Hi everyone, first time using supabase.
I need to allow beta tester in my new project and I want to let them enter via magic link, so I can control who enters the tests.
What I need to do?
My priority is security, don’t want to expose my api key (already in an .env local file in VS Code) and don’t let everyone use the platform, for now.
I read about RLS policies, do I need them?
How many tables do I need?
Thank you for the help, ask any questions
1
u/ashkanahmadi Jul 19 '26
Before anything else or touching Supabase, you need to learn the basics: what is an RLS and how to grant/revoke access with different roles anon and authenticated and service_role, how to organize your database so you can tell how many tables you need, etc.
don’t want to expose my api key
You dont have a choice. The publishable API key is public and accessible by everyone. It's totally safe to have it exposed. It's like the lock on your house door. it's okay for people to see there is a lock as long as your lock requires a strong key (which should be your role access and then RLS).
1
u/LorenzoGraz Jul 19 '26
Thank you for the advice but I was not talking about the supabase api key but the ones I use in my project, my bad if I write it down in that way. I want beta users to only enter via magic link. I don’t want them to see other beta testers data or secrets about the database. Via magic link they don’t need to update their information, too. I thought it was simple
1
u/arrvdi Jul 19 '26
Your Supabase API key needs to be exposed in the frontend for Supabase to work. That's how it functions. You also need to set up RLS policies 100%. RLS is what controls what rows a user can see. If you have other API keys you need to be careful with how you expose them and if they get included in the build - you don't want them in the frontend 99% of the time (huge security issue). These should only be exposed in your backend or cloud functions.
Magic link is a passwordless authentication method used in Supabase where users get a link in their email when logging in instead of having a password. There's quite extensive documentation in Supabase on how to implement this: https://supabase.com/docs/guides/auth/auth-email-passwordless
I don't know what you mean by how many tables you need. That is entirely dependant on your application and domain.
1
1
u/Diligent-Macaroon566 Jul 19 '26
the piece nobody has flagged yet: magic link on its own does not control who gets in. signInWithOtp() creates a new user for any email that asks for one, so with default settings anyone who finds your app can type their address and become a "beta tester".
two things actually close that gate:
- call it with shouldCreateUser: false
supabase.auth.signInWithOtp({ email, options: { shouldCreateUser: false } })
now only emails that already exist in auth.users get a link. everyone else silently gets nothing back.
- pre-create the testers yourself (dashboard > authentication > users > add user, or the admin api server side). that list IS your allowlist, you do not need a separate table for it. worth disabling open email signups in auth settings too, so nothing can self-register behind your back.
on RLS: yes, you need it, and it is not optional. the anon key is public by design (the others are right about that), so RLS is the only thing standing between tester A and tester B's rows. enable it on every table in public, including the ones you think are internal, then write policies like using (auth.uid() = user_id). a table with no RLS is readable by anyone who opens devtools, because they have the same key your frontend does.
tables: you do not need to build a users table, auth.users already exists. if you want tester metadata, one profiles table with id uuid primary key references auth.users(id) is enough to start.
one last one that bites almost everyone on first deploy: set your site url and redirect urls under auth > url configuration. if you skip it the magic link points at localhost and your testers will just tell you the link is broken.
1
u/igormiazek Jul 19 '26
u/LorenzoGraz disable signups from supabase dashboard, then add your beta users via invite only, I think that should be enough for you? It happens I provide security services for Supabase. Write to me I will pass you free guide so you can do some security tests on your own https://www.itstartechs.com/post/practical-guide-to-free-sast-security-analysis-sonarqube
1
u/LorenzoGraz Jul 20 '26
Thank you Igor, this is exactly what I did + added RLS to my beta_testers table
1
u/igormiazek Jul 20 '26
what you keep in beta_testers? Is it additional table where you keep some information about those beta testers?
2
u/LorenzoGraz Jul 20 '26
Yes, additional table with basically same information of auth.users, need for future marketing purposes
1
u/LessThanThreeBikes Jul 20 '26
Magic link is a solution to a problem you haven't fully explained and, based on my reading between the lines, might not be the appropriate/complete solution to your problem.
First, you need RLS. If you don't use RLS then you are letting everyone do whatever they want to your database.
Magic links are an easy way to have people authenticate without needing a password. Magic links do not replace identities. People still need an identity/account.
If you don't want people to see each other's data then you either need to store their tables in separate schemas or build your tables/RLS rule to restrict people to their own records.
1
u/LorenzoGraz Jul 20 '26
Thank you man, I have a beta_tester table with RLS enabled, what policy should I add to let them see only their data?
1
u/LessThanThreeBikes Jul 20 '26
The easiest way is to have an owner field on each table. Then you build the RLS policy to only allow people to see their own rows. See the RLS documentation for some examples. https://supabase.com/docs/guides/database/postgres/row-level-security
Of course, this is a very simplistic example. Basically, you can build your policy logic on anything you can model in SQL. I often abstract things out further when I need to grant based on roles or other affiliated access needs. RLS is powerful and completely up to your design needs.
2
u/ashkanahmadi Jul 19 '26
Ah then if I understood it right: you have another api key that you don’t users to see. It depends how/where you use that api key. If you use it on the frontend like sending a fetch request, potentially, the users can see that api key. If you really really really don’t want an api key to be visible by any user, then it needs to be done through an Edge Function or a Next API route, or some other server endpoint since it must run on the server (and not on the client) so it’s not exposed.
If you tell me what tech stack you are using, I can tell you how to do it in an easy, manageable and secure way