Overview
Security is critical for a gambling application handling user funds and sensitive data. This guide covers all security layers in Cajas, from database-level Row Level Security (RLS) to API protection and secrets management.Row Level Security (RLS)
Understanding RLS
Row Level Security ensures users can only access data they’re authorized to see. Every database table in Cajas has RLS enabled and enforced through PostgreSQL policies.RLS policies are defined in
supabase/migrations/20240101000000_init.sql:16-128RLS Policies by Table
users - Public Profiles
users - Public Profiles
Table: Security Implications:
public.usersSecurity Model: Public read, authenticated write- Usernames and avatars are public (for leaderboards, chat)
- Balance is visible but cannot be modified by users
- Only authenticated users can create/update their profile
cases - Game Catalog
cases - Game Catalog
Table: Security Implications:
public.casesSecurity Model: Public read-only- All users can browse available cases
- No write access through RLS (admin-only via service role)
- Case prices and items are public information
items - Prize Pool
items - Prize Pool
Table: Security Implications:
public.itemsSecurity Model: Public read-only- Item rarities and values are transparent
- No write access through standard authentication
- Ensures provably fair odds are verifiable
user_items - Inventory
user_items - Inventory
Table: Security Implications:
public.user_itemsSecurity Model: Private, user-scoped- Users can ONLY see their own inventory
- Prevents inventory snooping
- No write access (items added via API routes with validation)
transactions - Financial Records
transactions - Financial Records
Table: Security Implications:
public.transactionsSecurity Model: Private, user-scoped- Complete financial privacy
- Users cannot see others’ transaction history
- Immutable audit trail (no update/delete policies)
user_seeds - Provably Fair Data
user_seeds - Provably Fair Data
Table: Security Implications:
public.user_seedsSecurity Model: Private, user-scoped- Server seed remains secret until revealed
- Users can update client seed for fairness
- Nonce prevents replay attacks
game_rolls - Game Audit Log
game_rolls - Game Audit Log
Table: Security Implications:
public.game_rollsSecurity Model: Private, user-scoped read-only- Complete game history for verification
- Immutable record (no update/delete)
- Enables provably fair verification
Testing RLS Policies
Verify RLS policies are working correctly:API Route Security
Authentication Middleware
All API routes must verify user authentication:app/api/cases/open/route.ts:5-11
Input Validation
Validate all user inputs to prevent injection attacks:Rate Limiting
Protect API routes from abuse:middleware.ts
For production, use Vercel’s Edge Config or Upstash Redis for distributed rate limiting.
Secrets Management
Environment Variable Security
Public Variables
Safe to expose in client-side code:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
Secret Variables
NEVER expose to client:
SUPABASE_SERVICE_ROLE_KEY- Payment processor keys
- API secrets
Vercel Environment Variables
Store secrets securely in Vercel:Scope Correctly
- Production: Live environment only
- Preview: PR deployments (use test keys)
- Development: Local development
Secret Rotation
Rotate secrets regularly:Supabase Keys
Supabase Keys
- Generate new anon key in Supabase dashboard
- Update
NEXT_PUBLIC_SUPABASE_ANON_KEYin Vercel - Deploy new version
- Revoke old key after 24 hours
Service Role Key
Service Role Key
- Generate new service role key
- Update
SUPABASE_SERVICE_ROLE_KEY - Test API routes
- Deploy to production
- Revoke old key immediately
User Passwords
User Passwords
Enforce password rotation policy:
Authentication Security
Supabase Auth Configuration
Configure secure authentication settings:- Password Policy
- Session Management
- OAuth Providers
Enforce strong passwords in Supabase dashboard:
- Go to Authentication → Settings
- Configure password requirements:
- Minimum length: 12 characters
- Require uppercase
- Require numbers
- Require special characters
- Enable password breach detection
Cookie Security
Supabase auth cookies are configured securely:lib/supabase/server.ts:11-25
Supabase automatically sets secure cookie flags:
HttpOnly: Prevents JavaScript accessSecure: HTTPS onlySameSite=Lax: CSRF protection
CORS and CSRF Protection
CORS Configuration
Next.js API routes are same-origin by default. For external API access:middleware.ts
CSRF Protection
Supabase auth provides CSRF protection automatically. For additional API routes:Security Headers
Configure security headers invercel.json:
vercel.json
Security Checklist
Before deploying to production:Database Security
- RLS enabled on all tables
- Policies tested for user isolation
- Service role key secured
- Migrations reviewed
API Security
- Authentication verified on all routes
- Input validation implemented
- Rate limiting configured
- Error messages don’t leak info
Secrets Management
- No secrets in code/git
- Environment variables configured
- Production keys rotated
- Service accounts use least privilege
Client Security
- CSP headers configured
- XSS protection enabled
- HTTPS enforced
- Secure cookies enabled
Security is an ongoing process. Regularly review logs, update dependencies, and stay informed about security best practices.
Resources
Supabase Security
Official RLS documentation
Next.js Security
Next.js security best practices
OWASP Top 10
Common web vulnerabilities
Monitoring Setup
Configure security monitoring
