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#
| Task | Prompt |
|---|---|
| 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};Related Agents#
- Security Expert - Security best practices
- Backend Expert - API protection
- Database Expert - User data management