Skip to Content
Self-HostingSecurity

Security

BuildPad DaaS uses a defence-in-depth approach with security enforced at three layers.

Security Layers

LayerMechanism
DatabasePostgreSQL Row-Level Security (RLS) policies
APIPermission rule enforcement per route
ApplicationJWT validation, session management, input validation

Authentication Methods

MethodRLS ProtectionBest For
Cookie/Session✅ Database-levelWeb UI
JWT Bearer Token✅ Database-levelSecure API clients
Static Token⚠️ App-layer onlyAutomation, CI/CD

Static tokens use the Supabase service role internally, which bypasses database RLS. Application-layer permissions still apply. Use JWT tokens where database-level isolation is critical.

If SUPABASE_JWT_SECRET is set, JWT bearer tokens are verified in-process instead of per-request against GoTrue (faster). Security trade-off: a session revoked via logout stays valid until the token expires — per-request user-status checks still apply, and only users with an active daas_users row use the local path. Leave it unset where immediate revocation matters.

Row-Level Security

RLS policies are applied to all core system tables. Enable RLS on your custom tables using the generic RLS helper function:

-- Enable RLS on a custom table ALTER TABLE your_table ENABLE ROW LEVEL SECURITY; -- Apply the generic read policy (requires auth) CREATE POLICY "authenticated_read" ON your_table FOR SELECT USING (auth.uid() IS NOT NULL);

For the full generic RLS setup that automatically applies policies to new tables, run the corresponding migration in supabase/migrations/.

Audit Logging

Every create, update, and delete performed through the API is logged to daas_activity by the application layer (fire-and-forget, from ItemsService). Database-level audit triggers were removed — writes made directly in SQL bypass the audit log. The audit level is configurable per collection via daas_collections.accountability (all = log with full revisions, activity = log without revisions, NULL = no logging). Query the audit log via:

GET /api/revisions — paginated activity log (admin only) GET /api/revisions/:id — single activity entry

Production Checklist

  • ✅ Set explicit allowed origins in Settings → CORS (never *) — the CORS_ORIGINS env var is only a fallback used before migrations run; on upgraded databases verify the stored origins list no longer contains the legacy wildcard
  • ✅ Use HTTPS in production (via TLS termination at load balancer or nginx)
  • ✅ Set NEXT_TELEMETRY_DISABLED=1
  • ✅ Restrict the EC2 security group: only ports 80/443 public, 22 restricted
  • ✅ Rotate the SUPABASE_SERVICE_ROLE_KEY if compromised
  • ✅ Use IAM roles for EC2 instead of static AWS credentials
  • ⬜ Configure rate limiting (not built-in — use nginx limit_req or an API gateway)
Last updated on