Agent skill

auth

Authentication and access control skill for Next.js 15 + Supabase applications. Use when implementing user authentication, protecting routes, managing user sessions, enforcing role-based access control (admin/member), or working with multi-tenant family-based data isolation. Covers login/logout, registration with email verification, OAuth (GitHub), route protection for Server Components and Server Actions, admin-only features, and multi-tenant data access patterns.

Stars 232
Forks 15

Install this agent skill to your Project

npx add-skill https://github.com/aiskillstore/marketplace/tree/main/skills/bom-98/auth

SKILL.md

Authentication & Access Control

This skill provides workflows for implementing authentication and access control in this Next.js 15 + Supabase application using server-side auth with httpOnly cookies, hybrid route protection, and multi-tenant family-based data isolation.

System Overview

  • Auth Provider: Supabase Auth with httpOnly cookies
  • Architecture: Next.js 15 App Router with Server Components and Server Actions
  • Route Protection: Hybrid approach (page-level auth checks, not middleware-only)
  • Multi-Tenancy: Family-based data isolation with RLS policies
  • Roles: Admin (first user in family) and Member

Core Workflows

Protecting a New Route

To protect a route from unauthenticated users:

  1. Import requireAuthRedirect from @/lib/auth/server-auth
  2. Call await requireAuthRedirect() at the start of the component
  3. User will be redirected to /login if not authenticated
typescript
import { requireAuthRedirect } from '@/lib/auth/server-auth';

export default async function ProtectedPage() {
  await requireAuthRedirect();

  // User guaranteed authenticated here
  return <YourContent />;
}

To protect an entire route group, add this to the layout component. All child routes will inherit the protection.

Protecting a Server Action

To require authentication in a Server Action:

  1. Import requireAuth from @/lib/auth/server-auth
  2. Call const user = await requireAuth() at the start of the action
  3. Action will throw UnauthorizedError if user not authenticated
typescript
'use server';
import { requireAuth } from '@/lib/auth/server-auth';

export async function myAction() {
  const user = await requireAuth();

  // Proceed with authenticated action
}

Getting Current User Data

  • getCurrentUser() - Auth user (email, id), returns null if not logged in
  • getUserData() - Extended profile (role, familyId, firstName, lastName, active)
  • getCurrentFamilyId() - Just the family ID

All use React cache() - multiple calls in same request return cached value.

Implementing Admin-Only Features

To restrict a page to admins:

typescript
import { requireAdminRedirect } from '@/lib/auth/server-auth';

export default async function AdminPage() {
  await requireAdminRedirect();

  // User guaranteed to be admin
  return <AdminPanel />;
}

To restrict a Server Action to admins:

typescript
'use server';
import { requireAdmin } from '@/lib/auth/server-auth';

export async function adminAction() {
  await requireAdmin(); // Throws if not admin
  // Proceed
}

To conditionally show admin UI:

typescript
import { isAdmin } from '@/lib/auth/server-auth';

export default async function Page() {
  const userIsAdmin = await isAdmin();

  return (
    <>
      <RegularContent />
      {userIsAdmin && <AdminControls />}
    </>
  );
}

Enforcing Multi-Tenant Data Access

To ensure users only access their own family's data:

typescript
'use server';
import { requireFamilyAccess } from '@/lib/auth/server-auth';

export async function updateFamilyData(familyId: string, data: any) {
  await requireFamilyAccess(familyId); // Throws if user not in this family

  // User guaranteed to belong to this family
  await updateDatabase(familyId, data);
}

When fetching current user's family data, use getCurrentFamilyId() instead - no need for requireFamilyAccess since it's their own family.

Adding a New Authentication Page

To create a new auth page (login, register, password reset):

  1. Create page under src/app/(auth)/page-name/
  2. The (auth) group layout automatically redirects authenticated users to /dashboard
  3. Create corresponding Server Action in actions.ts file
  4. Import and use Supabase client: const supabase = await createClient()

Pages in (auth) group are automatically protected from authenticated users - they'll be redirected to dashboard if already logged in.

Implementing Login/Logout

Use supabase.auth.signInWithPassword() for login and supabase.auth.signOut() for logout. See references/patterns.md for complete code examples.

Adding OAuth Providers

  1. Enable provider in Supabase Dashboard
  2. Use supabase.auth.signInWithOAuth({ provider: 'github', options: {...} })
  3. Callback handled automatically by src/app/auth/callback/route.ts

See references/patterns.md for full implementation examples.

Security Requirements

Token Validation

  • Always use supabase.auth.getUser() to validate tokens (revalidates with server)
  • Never use supabase.auth.getSession() in server code (can be spoofed)

Server-Side Only

  • All auth helpers in src/lib/auth/server-auth.ts are server-side only
  • Never import these in Client Components
  • Never add 'use server' directive to server-auth.ts (breaks class exports)

Middleware

  • Middleware automatically refreshes tokens on every request
  • Uses updateSession() from src/lib/supabase/middleware.ts
  • Calls getUser() to revalidate tokens
  • No additional token refresh logic needed

Reference Files

For detailed information, see:

  • references/file-tree.md - Complete file structure and organization
  • references/security.md - Security best practices and requirements
  • references/patterns.md - Code examples and common patterns
  • references/flows.md - Authentication flow diagrams

Quick Reference

Key Files: src/lib/auth/server-auth.ts (helpers), src/middleware.ts (token refresh), src/app/dashboard/layout.tsx (dashboard protection)

Environment: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, NEXT_PUBLIC_SITE_URL

Database: auth.users (Supabase auth), public.families (households), public.users (profiles)

Common Issues

'use server' export error: Remove 'use server' from server-auth.ts - these are utilities, not actions

Middleware redirect fails: Use requireAuth() in Server Actions - middleware redirects don't work with POST

Multi-tenant access denied: Use requireFamilyAccess(familyId) to validate family ownership

Expand your agent's capabilities with these related and highly-rated skills.

aiskillstore/marketplace

perigon-backend

Perigon ASP.NET Core + EF Core + Aspire conventions

232 15
Explore
aiskillstore/marketplace

perigon-agent

Pointers for Copilot/agents to apply Perigon conventions

232 15
Explore
aiskillstore/marketplace

perigon-angular

Angular 21+ standalone/Material/signal conventions for Perigon WebApp

232 15
Explore
aiskillstore/marketplace

fastapi-mastery

Comprehensive FastAPI development skill covering REST API creation, routing, request/response handling, validation, authentication, database integration, middleware, and deployment. Use when working with FastAPI projects, building APIs, implementing CRUD operations, setting up authentication/authorization, integrating databases (SQL/NoSQL), adding middleware, handling WebSockets, or deploying FastAPI applications. Triggered by requests involving .py files with FastAPI code, API endpoint creation, Pydantic models, or FastAPI-specific features.

232 15
Explore
aiskillstore/marketplace

context7-efficient

Token-efficient library documentation fetcher using Context7 MCP with 86.8% token savings through intelligent shell pipeline filtering. Fetches code examples, API references, and best practices for JavaScript, Python, Go, Rust, and other libraries. Use when users ask about library documentation, need code examples, want API usage patterns, are learning a new framework, need syntax reference, or troubleshooting with library-specific information. Triggers include questions like "Show me React hooks", "How do I use Prisma", "What's the Next.js routing syntax", or any request for library/framework documentation.

232 15
Explore
aiskillstore/marketplace

browser-use

Browser automation using Playwright MCP. Navigate websites, fill forms, click elements, take screenshots, and extract data. Use when tasks require web browsing, form submission, web scraping, UI testing, or any browser interaction.

232 15
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results