Server Actions and Auth Guard Order
Enforces secure request handling sequences for server actions.
Install
mkdir -p .claude/skills/server-actions-and-auth-guard-order && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/18545" && unzip -o skill.zip -d .claude/skills/server-actions-and-auth-guard-order && rm skill.zipInstalls to .claude/skills/server-actions-and-auth-guard-order
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Zod validation before data touch, auth guard sequence, authz inside the action, security headers.Key capabilities
- →Verify caller authentication before validation
- →Parse input using Zod schemas
- →Verify caller authorization on resources
- →Implement business logic after all guards pass
- →Return typed success/error shapes
How it works
The skill enforces a specific sequence of security checks: authentication, schema validation, and authorization, before executing any business logic.
Inputs & outputs
When to use Server Actions and Auth Guard Order
- →Secure server action route handlers
- →Implement auth guard sequence
- →Validate Zod schema in actions
About this skill
Conventions for server actions, mutations, and auth guard sequencing. Source: guide-code.md §6, guide-arch.md.
Auth guard order (source: guide-arch.md)
Every route handler and server action must follow this exact sequence — auth before
validation, not the other way around. Checking auth first means an unauthenticated caller
never sees validation-error details or triggers any parsing/business-logic work; it's also what
the resolve-account-route-handler and api-error-handler skills already establish
(resolveAccount() as the first line), so this skill previously conflicted with those two.
- Auth check — verify the caller is authenticated; return 401 if not.
- Schema validate — parse input with zod; return 400 on failure.
- Authz check — verify the caller is authorized to act on the resource; return 403 if not.
- Business logic — only after all three guards pass.
// Good — correct guard sequence
export async function PUT(req: Request, { params }: { params: { id: string } }) {
// 1. Auth check
const account = await resolveAccount();
if (!account) return NextResponse.json({ error: "unauthorized" }, { status: 401 });
// 2. Schema validate
const body = await req.json();
const parsed = updateFlowSchema.safeParse(body);
if (!parsed.success) return NextResponse.json({ error: "validation" }, { status: 400 });
// 3. Authz check
const existing = await flowsRepository.getById(params.id, account.id);
if (!existing) return NextResponse.json({ error: "not_found" }, { status: 404 });
// 4. Business logic
await flowsRepository.update(params.id, account.id, parsed.data);
return NextResponse.json({ ok: true });
}
Server actions / mutations (source: guide-code.md §6)
- Check auth before validating input (see "Auth guard order" above — auth first, not validate first).
- Validate all input with zod before touching data.
- Perform authz checks inside the action/handler — not only in UI.
- Return typed success/error shapes; avoid leaking raw DB errors.
- Never trust client-side auth state for authorization decisions.
// Good
"use server";
export async function updateFlow(id: string, input: unknown) {
const account = await resolveAccount();
if (!account) return { error: "Unauthorized" };
const parsed = updateFlowSchema.safeParse(input);
if (!parsed.success) return { error: "Invalid input" };
await flowsRepository.update(id, account.id, parsed.data);
return { ok: true };
}
// Bad — no zod, no authz check, trusting the caller
("use server");
export async function updateFlow(id: string, data: FlowData) {
await db.update(flows).set(data).where(eq(flows.id, id));
}
RLS + app-layer filtering (source: guide-code.md §6, guide-db.md)
- Whether RLS is the primary boundary or the app-layer
accountIdfilter is depends on whether your product's DB connection is JWT-scoped per request, or a single shared pool that authenticates as one fixed role — seeskills/db/rls-policiesfor the full explanation. Don't assume RLS is doing the work without checking which model your product uses. - Both layers should be present regardless of which one is primary for your product.
- Never disable RLS as a workaround; fix the policy instead.
Security headers (source: guide-code.md §10)
Security headers are configured in next.config.mjs via the headers() function:
Content-Security-Policy— restrict script/style/connect sources.Strict-Transport-Security— HSTS with preload.X-Content-Type-Options,X-Frame-Options,Referrer-Policy,Permissions-Policy.
When adding a new external service (analytics, CDN, etc.), update connect-src
and any other relevant CSP directives.
Performance defaults (source: guide-code.md §13)
- Prefer Server Components and streaming; minimize client component boundaries.
- Use
next/imagefor all images — never raw<img>with external URLs. - Cache reads intentionally; revalidate explicitly after mutations.
// Good
import Image from "next/image";
<Image src={logo} alt="Logo" width={120} height={40} />
// Bad
<img src={logoUrl} alt="Logo" />
When not to use it
- →When authentication is not required for an endpoint
- →When validation should occur before authentication
- →When client-side auth state is trusted for authorization
Limitations
- →Requires explicit implementation of auth, validation, and authz checks in each handler
- →Does not automatically handle all security headers; some must be configured separately
- →Does not prevent leaking raw DB errors if not explicitly handled
How it compares
This approach prioritizes authentication before validation, preventing unauthenticated callers from accessing validation error details or triggering business logic.
Compared to similar skills
Server Actions and Auth Guard Order side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| Server Actions and Auth Guard Order (this skill) | 0 | 18d | No flags | Intermediate |
| middleware-protection | 1 | 5mo | Review | Intermediate |
| vercel-data-handling | 1 | 10d | No flags | Intermediate |
| firebase | 20 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
middleware-protection
dadbodgeoff
Protect routes with Next.js middleware. Check authentication once, protect routes declaratively. Supports public routes, protected routes, and role-based access.
vercel-data-handling
jeremylongshore
Implement Vercel PII handling, data retention, and GDPR/CCPA compliance patterns. Use when handling sensitive data, implementing data redaction, configuring retention policies, or ensuring compliance with privacy regulations for Vercel integrations. Trigger with phrases like "vercel data", "vercel PII", "vercel GDPR", "vercel data retention", "vercel privacy", "vercel CCPA".
firebase
davila7
Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting. But the ease of setup hides real complexity. Security rules are your last line of defense, and they're often wrong. Firestore queries are limited, and you learn this after you've designed your data model. This skill covers Firebase Authentication, Firestore, Realtime Database, Cloud Functions, Cloud Storage, and Firebase Hosting. Key insight: Firebase is optimized for read-heavy, denormalized data. I
server-action-pattern
JKKN-Institutions
Create or modify a Next.js Server Action for the JKKN institution website following the project's mandatory pattern. This skill should be used when the user asks to "add a server action", "create a mutation", "wire up a form submit", "add create/update/delete logic", "save/update/delete an entity",
skills
xDaijobu
How to work with TLS Watch - a TLS certificate monitoring application
security-review
AugustSnow1127
Security checklist and best practices for the personal blog project