Skip to Content
Welcome to the official DBS Documentation! 📚
AdvancedAPI Guard

API Guard

The apiGuard utility is the standard way to protect all API routes in DBS. It provides a single function that combines session checking, rate limiting, and optional permission-based authorization in one call.

Location

src/lib/api-guard.ts

How It Works

apiGuard runs three checks in sequence when called at the start of an API route handler:

  1. Session Check — Verifies the user is authenticated via Better Auth.
  2. Rate Limit Check — Enforces a default limit of 200 requests per 60 seconds per user.
  3. Permission Check (optional) — If a permission string is passed, verifies the user holds that permission (super admins bypass this check automatically).

Basic Usage

// User must be logged in, no specific permission needed export async function GET() { const guard = await apiGuard(); if (guard.error) return guard.error; // Returns 401 if not authenticated const { session } = guard; // session.user.id, session.user.email, etc. are available }

Return Type

The function always returns a GuardResult union type. Always check .error before accessing .session.

type GuardSuccess = { error: null; session: { user: { id, email, name, permissions: string[], roles: string[] } }; }; type GuardFailure = { error: NextResponse; // Ready-to-return error response (401 / 403 / 429) session: null; };

Error Responses

ConditionHTTP StatusMessage
Not authenticated401 UnauthorizedLogin required
Rate limit exceeded429 Too Many RequestsRate limit exceeded, please try again later.
Missing permission403 ForbiddenMissing required permission: <permission>

Super Admin bypass: Users with the super_admin role automatically pass all permission checks. They are still subject to rate limiting.

Creating New Protected Routes

When adding a new API route, always start with apiGuard. Check the RBAC permission list in src/lib/rbac/permission.ts to find the correct permission key to use.

// src/app/api/my-feature/route.ts import { apiGuard } from '@/lib/api-guard'; import { NextResponse } from 'next/server'; export async function POST(req: Request) { const guard = await apiGuard('my_feature.write'); if (guard.error) return guard.error; const { session } = guard; const body = await req.json(); // ... your logic here return NextResponse.json({ success: true }); }
Last updated on