Auth Expert

The Auth Expert agent specializes in authentication patterns, session management, OAuth, protected routes, and security best practices for web applications.

Expertise Areas#

  • Clerk Authentication - Modern auth provider integration
  • NextAuth.js (Auth.js) - Self-hosted authentication
  • Protected Routes - Middleware and route protection
  • Role-Based Access Control - RBAC implementation
  • Session Management - JWT and cookie sessions
  • OAuth Flow - Third-party provider integration
  • Webhook Integration - User sync and events

Usage Examples#

Clerk Setup#

Use the auth-expert agent to set up Clerk authentication with protected routes in a Next.js app.

Response includes:

  • Middleware configuration
  • Provider setup
  • Protected route patterns
  • Auth component usage

NextAuth.js Integration#

Use the auth-expert agent to implement NextAuth.js with Google and GitHub providers plus email/password.

Response includes:

  • Provider configuration
  • Prisma adapter setup
  • Callback customization
  • Session handling

RBAC Implementation#

Use the auth-expert agent to implement role-based access control for admin and user roles.

Response includes:

  • Role definition
  • Permission checking
  • Protected API routes
  • UI authorization

Best Practices Applied#

1. Authentication#

  • Secure session management
  • Token handling best practices
  • Multi-provider support
  • Password security

2. Authorization#

  • Role-based access control
  • Permission granularity
  • Resource-level permissions
  • Admin override patterns

3. Security#

  • CSRF protection
  • Secure cookies
  • Token expiration
  • Session invalidation

4. Integration#

  • Database sync via webhooks
  • User profile management
  • Account linking
  • SSO support

Common Patterns#

Clerk Middleware#

1// middleware.ts 2import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'; 3 4const isPublicRoute = createRouteMatcher([ 5 '/', 6 '/sign-in(.*)', 7 '/sign-up(.*)', 8 '/api/webhooks(.*)', 9]); 10 11export default clerkMiddleware((auth, req) => { 12 if (!isPublicRoute(req)) { 13 auth().protect(); 14 } 15}); 16 17export const config = { 18 matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'], 19};

NextAuth.js Configuration#

1// auth.ts 2import NextAuth from 'next-auth'; 3import GitHub from 'next-auth/providers/github'; 4import Google from 'next-auth/providers/google'; 5import { PrismaAdapter } from '@auth/prisma-adapter'; 6import { prisma } from '@/lib/db'; 7 8export const { handlers, auth, signIn, signOut } = NextAuth({ 9 adapter: PrismaAdapter(prisma), 10 session: { strategy: 'jwt' }, 11 providers: [ 12 GitHub({ 13 clientId: process.env.GITHUB_ID, 14 clientSecret: process.env.GITHUB_SECRET, 15 }), 16 Google({ 17 clientId: process.env.GOOGLE_ID, 18 clientSecret: process.env.GOOGLE_SECRET, 19 }), 20 ], 21 callbacks: { 22 async jwt({ token, user }) { 23 if (user) token.id = user.id; 24 return token; 25 }, 26 async session({ session, token }) { 27 if (session.user) session.user.id = token.id as string; 28 return session; 29 }, 30 }, 31});

Role-Based Access Control#

1// lib/rbac.ts 2import { auth } from '@/auth'; 3import { prisma } from '@/lib/db'; 4 5export type Role = 'USER' | 'ADMIN' | 'SUPER_ADMIN'; 6 7export async function requireRole(allowedRoles: Role[]) { 8 const session = await auth(); 9 10 if (!session?.user) { 11 throw new Error('Unauthorized'); 12 } 13 14 const user = await prisma.user.findUnique({ 15 where: { id: session.user.id }, 16 select: { role: true }, 17 }); 18 19 if (!allowedRoles.includes(user?.role as Role)) { 20 throw new Error('Forbidden'); 21 } 22 23 return { session, role: user?.role }; 24}

User Sync Webhook#

1// app/api/webhooks/clerk/route.ts 2import { Webhook } from 'svix'; 3import { headers } from 'next/headers'; 4import { WebhookEvent } from '@clerk/nextjs/server'; 5import { prisma } from '@/lib/db'; 6 7export async function POST(req: Request) { 8 const body = await req.text(); 9 const headerPayload = headers(); 10 11 const svix = new Webhook(process.env.CLERK_WEBHOOK_SECRET!); 12 let event: WebhookEvent; 13 14 try { 15 event = svix.verify(body, { 16 'svix-id': headerPayload.get('svix-id')!, 17 'svix-timestamp': headerPayload.get('svix-timestamp')!, 18 'svix-signature': headerPayload.get('svix-signature')!, 19 }) as WebhookEvent; 20 } catch { 21 return Response.json({ error: 'Invalid signature' }, { status: 400 }); 22 } 23 24 switch (event.type) { 25 case 'user.created': 26 await prisma.user.create({ 27 data: { 28 clerkId: event.data.id, 29 email: event.data.email_addresses[0].email_address, 30 }, 31 }); 32 break; 33 } 34 35 return Response.json({ received: true }); 36}

Sample Prompts#

TaskPrompt
Clerk setup"Set up Clerk authentication with protected dashboard routes"
NextAuth"Configure NextAuth.js with OAuth providers and Prisma"
RBAC"Implement role-based access control for API routes"
Session"Set up secure session management with JWTs"
Webhook"Create user sync webhook for Clerk events"

Configuration#

1// bootspring.config.js 2module.exports = { 3 agents: { 4 customInstructions: { 5 'auth-expert': ` 6 - Use Clerk for managed authentication 7 - Implement proper middleware protection 8 - Set up role-based access control 9 - Configure webhook for user sync 10 - Follow security best practices 11 `, 12 }, 13 }, 14 auth: { 15 provider: 'clerk', 16 roles: ['USER', 'ADMIN'], 17 }, 18};