supabase-prod-checklist

1
0
Source

Execute Supabase production deployment checklist and rollback procedures. Use when deploying Supabase integrations to production, preparing for launch, or implementing go-live procedures. Trigger with phrases like "supabase production", "deploy supabase", "supabase go-live", "supabase launch checklist".

Install

mkdir -p .claude/skills/supabase-prod-checklist && curl -L -o skill.zip "https://mcp.directory/api/skills/download/4213" && unzip -o skill.zip -d .claude/skills/supabase-prod-checklist && rm skill.zip

Installs to .claude/skills/supabase-prod-checklist

About this skill

Supabase Production Deployment Checklist

Overview

Actionable 14-step checklist for taking a Supabase project to production. Covers RLS enforcement, key separation, connection pooling (Supavisor), backups/PITR, network restrictions, custom domains, auth emails, rate limits, monitoring, Edge Functions, Storage policies, indexes, and migrations. Based on Supabase's official production guide.

Prerequisites

  • Supabase project on Pro plan or higher (required for PITR, network restrictions)
  • Separate production project (never share dev/prod)
  • @supabase/supabase-js v2+ installed
  • Supabase CLI installed (npx supabase --version)
  • Domain and DNS configured for custom domain
  • Deployment platform ready (Vercel, Netlify, Cloudflare, etc.)

Instructions

Step 1: Enforce Row Level Security on ALL Tables

RLS is the single most critical production requirement. Without it, any client with your anon key can read/write every row.

-- Audit: find tables WITHOUT RLS enabled
-- This query MUST return zero rows before going live
SELECT schemaname, tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public' AND rowsecurity = false;
-- Enable RLS on a table
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;

-- Create a basic read policy (authenticated users see own rows)
CREATE POLICY "Users can view own profile"
  ON public.profiles
  FOR SELECT
  USING (auth.uid() = user_id);

-- Create an insert policy
CREATE POLICY "Users can insert own profile"
  ON public.profiles
  FOR INSERT
  WITH CHECK (auth.uid() = user_id);

-- Create an update policy
CREATE POLICY "Users can update own profile"
  ON public.profiles
  FOR UPDATE
  USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);
  • RLS enabled on every public table (zero rows from audit query above)
  • SELECT, INSERT, UPDATE, DELETE policies defined for each table
  • Policies tested with both authenticated and anonymous roles
  • No tables use USING (true) without intent (public read tables only)

Step 2: Enforce Key Separation — Anon vs Service Role

The anon key is safe for client-side code. The service_role key bypasses RLS entirely and must never leave server-side environments.

// Client-side — ONLY use anon key
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!  // Safe for browsers
);
// Server-side only — service_role key (API routes, webhooks, cron jobs)
import { createClient } from '@supabase/supabase-js';

const supabaseAdmin = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!,  // NEVER expose to client
  { auth: { autoRefreshToken: false, persistSession: false } }
);
  • Anon key used in all client-side code (NEXT_PUBLIC_ prefix)
  • Service role key used only in server-side code (API routes, Edge Functions)
  • Service role key not in any client bundle (verify with grep -r "service_role" dist/)
  • Database password changed from the auto-generated default

Step 3: Configure Connection Pooling (Supavisor)

Supabase uses Supavisor for connection pooling. Serverless functions (Vercel, Netlify, Cloudflare Workers) MUST use the pooled connection string to avoid exhausting the database connection limit.

# Direct connection (migrations, admin tasks only)
postgresql://postgres:[PASSWORD]@db.[REF].supabase.co:5432/postgres

# Pooled connection via Supavisor (application code — USE THIS)
# Port 6543 = Supavisor pooler (vs 5432 direct)
postgresql://postgres.[REF]:[PASSWORD]@aws-0-us-east-1.pooler.supabase.com:6543/postgres
// For serverless environments — use pooled connection
const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_ANON_KEY!,
  {
    db: { schema: 'public' },
    // Supavisor handles pooling at port 6543
    // No need to configure pgBouncer settings in the client
  }
);
  • Application code uses pooled connection string (port 6543)
  • Direct connection reserved for migrations and admin tasks only
  • Connection string in deployment platform env vars (not hardcoded)
  • Verified pool mode: transaction for serverless, session for long-lived connections

Step 4: Enable Database Backups

Supabase provides automatic daily backups on Pro plan. Point-in-time recovery (PITR) enables granular restores.

  • Automatic daily backups enabled (Pro plan — verify in Dashboard > Database > Backups)
  • Point-in-time recovery configured (Dashboard > Database > Backups > PITR)
  • Tested restore procedure on a staging project (do not skip this)
  • Migration files committed to version control (supabase/migrations/ directory)
  • npx supabase db push tested against a fresh project to verify migrations replay cleanly

Step 5: Configure Network Restrictions

Restrict database access to known IP addresses. This prevents unauthorized direct database connections even if credentials leak.

  • IP allowlist configured (Dashboard > Database > Network Restrictions)
  • Only deployment platform IPs and team office IPs are allowed
  • Verified that application still connects after restrictions applied
  • Documented which IPs are allowed and why

Step 6: Configure Custom Domain

A custom domain replaces the default *.supabase.co URLs with your brand domain for API and auth endpoints.

  • Custom domain configured (Dashboard > Settings > Custom Domains)
  • DNS CNAME record added and verified
  • SSL certificate provisioned and active
  • Application code updated to use custom domain URL
  • OAuth redirect URLs updated to use custom domain

Step 7: Customize Auth Email Templates

Default Supabase auth emails show generic branding. Customize them so users see your domain and brand.

  • Confirmation email template customized (Dashboard > Auth > Email Templates)
  • Password reset email template customized
  • Magic link email template customized
  • Invite email template customized
  • Custom SMTP configured (Dashboard > Auth > SMTP Settings) — avoids rate limits and improves deliverability
  • Email confirmation enabled (Dashboard > Auth > Settings)
  • OAuth redirect URLs restricted to production domains only
  • Unused auth providers disabled

Step 8: Understand Rate Limits Per Tier

Supabase enforces rate limits that vary by plan. Hitting these in production causes 429 errors.

ResourceFreeProTeam
API requests500/min1,000/min5,000/min
Auth emails4/hour30/hour100/hour
Realtime connections200 concurrent500 concurrent2,000 concurrent
Edge Function invocations500K/month2M/month5M/month
Storage bandwidth2GB/month250GB/monthCustom
Database size500MB8GB50GB
  • Rate limits documented for your plan tier
  • Client-side retry logic with exponential backoff for 429 responses
  • Auth email rate limits understood (use custom SMTP to increase)
  • Realtime connection limits planned for expected concurrent users

Step 9: Review Monitoring Dashboards

Supabase provides built-in monitoring. Review these before launch to establish baselines.

// Health check endpoint — deploy this to your application
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_ANON_KEY!
);

export async function GET() {
  const start = Date.now();
  const { data, error } = await supabase
    .from('_health_check')  // Create a small table for this
    .select('id')
    .limit(1);

  const latency = Date.now() - start;

  return Response.json({
    status: error ? 'unhealthy' : 'healthy',
    latency_ms: latency,
    timestamp: new Date().toISOString(),
    supabase_reachable: !error,
  }, { status: error ? 503 : 200 });
}
  • Dashboard > Reports reviewed (API requests, auth, storage, realtime)
  • Dashboard > Logs > API checked for error patterns
  • Dashboard > Database > Performance Advisor reviewed and recommendations applied
  • Health check endpoint deployed and monitored (uptime service)
  • Error tracking configured (Sentry, LogRocket, etc.)
  • Alerts set for: error rate spikes, high latency, connection pool exhaustion

Step 10: Deploy Edge Functions with Proper Env Vars

Edge Functions run on Deno Deploy. Environment variables must be set via the Supabase CLI or Dashboard, not hardcoded.

# Set secrets for Edge Functions
npx supabase secrets set STRIPE_SECRET_KEY=sk_live_...
npx supabase secrets set RESEND_API_KEY=re_...

# List current secrets
npx supabase secrets list

# Deploy all Edge Functions
npx supabase functions deploy

# Deploy a specific function
npx supabase functions deploy process-webhook
// supabase/functions/process-webhook/index.ts
import { createClient } from '@supabase/supabase-js';

Deno.serve(async (req) => {
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!  // Available automatically
  );

  const body = await req.json();
  // Process webhook payload...

  return new Response(JSON.stringify({ received: true }), {
    headers: { 'Content-Type': 'application/json' },
  });
});
  • All Edge Functions deployed to production (npx supabase functions deploy)
  • Environment secrets set via npx supabase secrets set (not hardcoded)
  • SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY available automatically (no need to set)
  • Edge Functions tested with npx supabase functions serve locally before deploying
  • CORS headers configured for Edge Functions that receive browser requests

Step 11: Verify Storage Bucket Policies

Storage buckets need ex


Content truncated.

svg-icon-generator

jeremylongshore

Svg Icon Generator - Auto-activating skill for Visual Content. Triggers on: svg icon generator, svg icon generator Part of the Visual Content skill category.

6814

d2-diagram-creator

jeremylongshore

D2 Diagram Creator - Auto-activating skill for Visual Content. Triggers on: d2 diagram creator, d2 diagram creator Part of the Visual Content skill category.

2412

performing-penetration-testing

jeremylongshore

This skill enables automated penetration testing of web applications. It uses the penetration-tester plugin to identify vulnerabilities, including OWASP Top 10 threats, and suggests exploitation techniques. Use this skill when the user requests a "penetration test", "pentest", "vulnerability assessment", or asks to "exploit" a web application. It provides comprehensive reporting on identified security flaws.

379

designing-database-schemas

jeremylongshore

Design and visualize efficient database schemas, normalize data, map relationships, and generate ERD diagrams and SQL statements.

978

performing-security-audits

jeremylongshore

This skill allows Claude to conduct comprehensive security audits of code, infrastructure, and configurations. It leverages various tools within the security-pro-pack plugin, including vulnerability scanning, compliance checking, cryptography review, and infrastructure security analysis. Use this skill when a user requests a "security audit," "vulnerability assessment," "compliance review," or any task involving identifying and mitigating security risks. It helps to ensure code and systems adhere to security best practices and compliance standards.

86

django-view-generator

jeremylongshore

Generate django view generator operations. Auto-activating skill for Backend Development. Triggers on: django view generator, django view generator Part of the Backend Development skill category. Use when working with django view generator functionality. Trigger with phrases like "django view generator", "django generator", "django".

15

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

643969

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

591705

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

318398

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

339397

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

451339

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

304231

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.