AnotherWrapper includes several security features out of the box. This guide explains the existing security measures and shows how to implement optional rate limiting:
If you’ve followed the setup guides, Row Level Security (RLS) is already enabled and configured for all your tables, ensuring users can only access their own data.
Never disable RLS policies unless absolutely necessary.
User Ownership: Use auth.uid() to match the authenticated user with their data
Default Deny: Start with all access denied, then explicitly grant permissions
Minimal Access: Give users access only to what they absolutely need
Separate Policies: Create distinct policies for different operations (SELECT, INSERT, etc.)
Here’s an example of common RLS policies:
-- Enable RLSALTER TABLE "documents" ENABLE ROW LEVEL SECURITY;-- Users can only read their own documentsCREATE POLICY "Users can read own documents"ON "documents"FOR SELECTUSING (auth.uid() = user_id);-- Users can only insert documents they ownCREATE POLICY "Users can insert own documents"ON "documents"FOR INSERTWITH CHECK (auth.uid() = user_id);-- Users can only update their own documentsCREATE POLICY "Users can update own documents"ON "documents"FOR UPDATEUSING (auth.uid() = user_id)WITH CHECK (auth.uid() = user_id);-- Users can only delete their own documentsCREATE POLICY "Users can delete own documents"ON "documents"FOR DELETEUSING (auth.uid() = user_id);
These policies ensure that users can only access, modify, or delete their own data, while administrators can manage all records through superuser access.
Update the following files to implement rate limiting:
import { type NextRequest, NextResponse } from "next/server";import { updateSession } from "@/lib/utils/supabase/middleware";import { Ratelimit } from "@upstash/ratelimit";import { Redis } from "@upstash/redis";// Initialize Redis clientconst redis = new Redis({ url: process.env.UPSTASH_REDIS_REST_URL!, token: process.env.UPSTASH_REDIS_REST_TOKEN!,});// Configure rate limiter (example: 3 requests per minute)const ratelimit = new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(3, "60 s"),});// Routes to rate limitconst urlsToRateLimit = [ "/api/ai/generate", "/api/uploads", // Add your rate-limited routes];export async function middleware(request: NextRequest) { if (urlsToRateLimit.some((url) => request.url.includes(url))) { const ip = request.ip ?? "127.0.0.1"; const { success } = await ratelimit.limit(ip); if (!success) { const url = new URL(request.url); return url.pathname.startsWith("/api/") ? NextResponse.json({ error: "Rate limit exceeded" }, { status: 429 }) : NextResponse.redirect(new URL("/blocked", request.url)); } } return await updateSession(request);}export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) * Feel free to modify this pattern to include more paths. */ "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)", ],};
The middleware handles the rate limiting logic, while the blocked page provides a user-friendly interface when limits are exceeded. Users will be redirected to this page when they hit the rate limit on non-API routes.
Protect against AI service abuse by setting hard limits in your AI service dashboards:
Always set up budget alerts and hard limits in your AI service dashboards to
prevent unexpected costs.
All AI providers (OpenAI, Replicate, Anthropic, ElevenLabs, Groq) have built-in tools to regulate usage and set maximum spending limits. Make sure to configure these limits in each provider’s dashboard to prevent abuse and unexpected costs.