VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=eyJ...
| Key | Public? | Safe? | Why |
|---|---|---|---|
VITE_SUPABASE_URL |
Yes | Yes | Just a URL, contains no permissions |
VITE_SUPABASE_ANON_KEY |
Yes (by design) | Yes | Anon key is designed for public use. Protected by RLS, not the key itself |
| Service Role key | Never | Dangerous | Not used in this project — belongs on the server only |
Why is the
VITE_prefix OK? Vite includes keys with theVITE_prefix directly in the bundle — they are visible in the client-side JS. This is by design for the Supabase anon key. Data is protected by RLS policies at the database level.
*.local # catches .env.local
node_modules
dist
.env.local never ends up on GitHub.
Every table has RLS enabled. Users access the database directly from the browser (via the anon key), but RLS ensures they can only see their own data.
| Rule | Implementation |
|---|---|
| User can only see their own workspace | workspace_id = my_workspace_id() |
| Freelancer can only see assigned projects | is_project_member(project_id) |
| Notifications are user-specific | user_id = auth.uid() |
| Client view without authentication | SECURITY DEFINER RPC (controlled access) |
- Owner + PM: can see all workspace data
- Freelancer: can only see projects where they are in
project_members— enforced by RLS, cannot be bypassed
/workspace— accessible to Owner only/clients— accessible to Owner + PM
Frontend guards are a UX layer (user doesn't see the page). RLS is the security layer (user cannot get data even via API).
| Area | Solution |
|---|---|
| User auth | Supabase Auth (bcrypt internally) — we never see passwords |
| Share link password | pgcrypto — stored as bcrypt hash (crypt(password, gen_salt('bf'))) |
| Invite tokens | UUID v1 — single-use, unusable after acceptance/decline |
- Verify that
.env.localis not in the GitHub repository - Set Site URL in Supabase Auth (see DEPLOYMENT.md)
- Consider enabling Supabase Auth → Email confirmations for production
- Consider the Pro plan for automatic backups
- Do not push
.env.localto GitHub - Do not use the Service Role key on the frontend
- Do not expose the Supabase Service Role key anywhere
- Do not disable RLS on tables