When to rotate:
- Anon key exposed in public repo
- Suspected unauthorized access
- Regular rotation (every 90 days)
Steps:
- Go to Supabase Dashboard → Project Settings → API
- Click "Roll" next to anon/public key
- Copy the NEW anon key
- Update .env: VITE_SUPABASE_URL=same-url VITE_SUPABASE_ANON_KEY=NEW-KEY-HERE
- Update server/.env if used there
- Redeploy your frontend
- Old key is immediately invalidated
- Test login/signup still works
Warning: Rolling the anon key will immediately break any app still using the old key. Do during low-traffic hours.
The service role key has FULL database access. Treat it like a root password.
When to rotate:
- Key exposed anywhere (URGENT)
- Team member leaves
- Regular rotation (every 90 days)
Steps:
- Go to Supabase Dashboard → Project Settings → API
- Click "Roll" next to service_role key
- Copy the NEW service role key
- Update server/.env: SUPABASE_SERVICE_KEY=NEW-KEY-HERE
- Restart your Express server: cd server && npm start
- Test admin operations still work
- Old key is immediately invalidated
Warning: This breaks your server immediately. Have new key ready before rolling. Do this during maintenance window.
When to rotate:
- Key exposed in code/logs
- Suspected fraud
- Team member with access leaves
Steps:
- Go to Razorpay Dashboard → Settings → API Keys
- Click "Regenerate Test/Live Key"
- Download the new key pair
- Update server/.env: RAZORPAY_KEY_ID=rzp_test_NEW-KEY RAZORPAY_KEY_SECRET=NEW-SECRET
- Update frontend .env: VITE_RAZORPAY_KEY_ID=rzp_test_NEW-KEY
- Restart server
- Test a payment flow
- Old keys stop working immediately
Warning: Any in-flight payments using old keys will fail. Notify users if needed. Always rotate during low-traffic period.
Always do these steps after rotating:
□ Update .env files locally □ Update environment variables on hosting platform (Vercel/Railway/etc) □ Restart all server instances □ Clear any cached tokens □ Test critical user flows:
- Login/signup
- Station listing
- Booking flow
- Payment (if Razorpay rotated) □ Monitor error logs for 30 mins □ Update password manager/team vault
□ .env files are in .gitignore □ .env files NOT committed to git □ Service key only in server, never frontend □ Anon key is OK for frontend (by design) □ Keys rotated every 90 days □ Team access reviewed monthly □ Supabase RLS policies enabled □ Rate limiting enabled on API □ Helmet.js security headers active
If a secret key was committed to git:
IMMEDIATE STEPS (do in under 5 minutes):
- Rotate the key immediately (steps above)
- New key is live before old one matters
- Then clean git history: pip install git-filter-repo git filter-repo --path .env --invert-paths git push origin --force --all
- GitHub will also scan and alert you
- Check Supabase logs for unauthorized use
- Check Razorpay logs for unauthorized charges