Copy .env.example to .env.local and fill in your actual values:
cp .env.example .env.local-
NEXT_PUBLIC_SUPABASE_URL: Your Supabase project URL
- Get from: Supabase Dashboard → Your Project → Settings → API
- Safe to expose in browser (NEXT_PUBLIC_ prefix)
-
NEXT_PUBLIC_SUPABASE_ANON_KEY: Your Supabase anonymous key
- Get from: Supabase Dashboard → Your Project → Settings → API → anon/public key
- Safe to expose in browser - designed for client-side use
- Security enforced by Row Level Security (RLS) policies
-
SUPABASE_SERVICE_ROLE_KEY: Your Supabase service role key (OPTIONAL)
- Get from: Supabase Dashboard → Your Project → Settings → API → service_role key
⚠️ CRITICAL: Never expose this key to the browser- Currently not used in the application (good security practice)
- Only use for admin operations that bypass RLS
- Can be removed if you're certain you won't need admin database access
-
OPENROUTER_API_KEY: Your OpenRouter API key
- Get from: OpenRouter Keys
⚠️ KEEP SECRET: This key incurs costs and should never be exposed- Used server-side only for AI personality analysis
-
OPENROUTER_MODEL: AI model to use (default: anthropic/claude-3.5-haiku)
- Row Level Security: All database operations enforce user ownership
- Server-side API routes: Sensitive operations happen server-side
- Input validation: API endpoints validate required fields
- Authentication checks: All protected routes verify user authentication
- Service role key: Not used (prevents accidental RLS bypass)
-
Supabase Anon Key Exposure:
- This is normal and safe for Supabase
- Real security comes from RLS policies
- Monitor usage in Supabase dashboard
-
API Rate Limiting:
- OpenRouter API calls should be rate-limited
- Consider implementing request queuing for heavy usage
-
Input Sanitization:
- User inputs are validated but not fully sanitized
- Consider adding XSS protection for text content
All tables have Row Level Security enabled:
-- Users can only access their own profiles
ALTER TABLE personality_profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own profiles" ON personality_profiles
FOR SELECT USING (auth.uid() = user_id);
-- Users can only access their own templates
ALTER TABLE communication_templates ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own templates" ON communication_templates
FOR SELECT USING (auth.uid() = user_id);All API routes verify authentication:
const { data: { user }, error: authError } = await supabase.auth.getUser()
if (authError || !user || user.id !== userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}Consider implementing rate limiting for:
- Profile creation (prevent spam)
- AI analysis requests (prevent API abuse)
- Template creation (prevent database flooding)
Never commit real values to git:
- Use your hosting platform's environment variable system
- Rotate keys regularly
- Monitor API usage for unusual activity
Ensure all production traffic uses HTTPS:
- Supabase automatically uses HTTPS
- Configure your hosting platform for HTTPS
- Update NEXT_PUBLIC_SITE_URL to use https:// in production
Monitor in Supabase dashboard:
- API usage and quotas
- Authentication logs
- Database performance
- RLS policy effectiveness
Monitor in OpenRouter dashboard:
- API costs and usage
- Rate limit status
- Error rates
Before deployment:
- All environment variables use placeholders in .env.example
- Real API keys are not committed to version control
- .env.local is in .gitignore
- RLS policies are enabled and tested
- API endpoints validate authentication
- HTTPS is configured in production
- Monitoring is set up for API usage
If API keys are compromised:
- Supabase: Regenerate keys in dashboard, update environment variables
- OpenRouter: Regenerate API key, monitor for unauthorized usage
- Review logs: Check for unauthorized access or unusual patterns
- Update credentials: Ensure new keys are properly secured
For PersonaFlow security concerns or questions:
- Review this documentation first
- Check Supabase and OpenRouter documentation
- Consider security audit for production deployment