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.
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:
- Import
requireAuthRedirectfrom@/lib/auth/server-auth - Call
await requireAuthRedirect()at the start of the component - User will be redirected to
/loginif not authenticated
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:
- Import
requireAuthfrom@/lib/auth/server-auth - Call
const user = await requireAuth()at the start of the action - Action will throw
UnauthorizedErrorif user not authenticated
'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 ingetUserData()- 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:
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:
'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:
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:
'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):
- Create page under
src/app/(auth)/page-name/ - The
(auth)group layout automatically redirects authenticated users to/dashboard - Create corresponding Server Action in
actions.tsfile - 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
- Enable provider in Supabase Dashboard
- Use
supabase.auth.signInWithOAuth({ provider: 'github', options: {...} }) - 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.tsare server-side only - Never import these in Client Components
- Never add
'use server'directive toserver-auth.ts(breaks class exports)
Middleware
- Middleware automatically refreshes tokens on every request
- Uses
updateSession()fromsrc/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 organizationreferences/security.md- Security best practices and requirementsreferences/patterns.md- Code examples and common patternsreferences/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
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
perigon-backend
Perigon ASP.NET Core + EF Core + Aspire conventions
perigon-agent
Pointers for Copilot/agents to apply Perigon conventions
perigon-angular
Angular 21+ standalone/Material/signal conventions for Perigon WebApp
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.
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.
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.
Didn't find tool you were looking for?