Install
$ agentstack add skill-zebbern-claude-code-guide-authentication-patterns ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Authentication Patterns Skill
Reference for implementing secure, production-ready authentication.
WHENTOUSE
Apply this skill when implementing authentication in a project, reviewing existing auth flows for security issues, choosing between auth providers, or migrating between auth strategies. Use the security checklist before shipping any auth-related change.
AUTH_APPROACHES
| Approach | How It Works | Best For | Drawbacks | |----------|-------------|----------|-----------| | Session-based | Server stores session in DB/Redis, client holds session ID cookie | Traditional server-rendered apps, apps needing instant revocation | Requires server-side storage, harder to scale horizontally without shared store | | JWT (stateless) | Server signs token, client sends it on each request | API-first apps, microservices, mobile clients | Cannot revoke without blocklist, token size grows with claims | | OAuth 2.0 / OIDC | Delegates auth to external provider (Google, GitHub, etc.) | Social login, enterprise SSO, reducing auth responsibility | More complex flow, depends on external provider availability | | Passkeys / WebAuthn | Cryptographic key pair, no passwords | High-security apps, passwordless UX | Limited browser support legacy, user education needed |
Decision Guide
- Server-rendered app with simple needs → Session-based
- SPA or mobile app calling APIs → JWT with refresh token rotation
- Want social login or SSO → OAuth 2.0 / OIDC
- Greenfield with modern UX goals → Passkeys + OAuth fallback
JWTBESTPRACTICES
Token Lifecycle
Login → Access Token (short-lived) + Refresh Token (long-lived, rotated)
│
├─ Access Token: 15 min expiry, sent via httpOnly cookie or Authorization header
│
└─ Refresh Token: 7-30 day expiry, stored in httpOnly secure cookie
│
└─ On use: issue new access + new refresh token, invalidate old refresh token
Rules
- [P0-MUST] Set short expiry on access tokens (15 minutes or less).
- [P0-MUST] Store tokens in
httpOnly,Secure,SameSite=Laxcookies — never inlocalStorageorsessionStorage. - [P0-MUST] Implement refresh token rotation — each refresh token is single-use.
- [P0-MUST] Maintain a server-side blocklist for revoked refresh tokens.
- [P1-SHOULD] Include only essential claims in JWT payload (sub, iat, exp, role). Keep it small.
- [P1-SHOULD] Use asymmetric signing (RS256 or ES256) for distributed systems; symmetric (HS256) for single-service only.
- [P1-SHOULD] Validate
iss,aud, andexpclaims on every request. - [P2-MAY] Use JWE (encrypted JWT) when token payload contains sensitive data.
Token Storage Comparison
| Storage | XSS Safe | CSRF Safe | Recommendation | |---------|----------|-----------|----------------| | httpOnly cookie | Yes | No (needs CSRF token) | Recommended | | localStorage | No | Yes | Never use for auth tokens | | sessionStorage | No | Yes | Never use for auth tokens | | In-memory (JS variable) | Yes | Yes | OK for SPAs, lost on refresh |
PROVIDER_PATTERNS
Comparison
| Provider | Type | Best For | Pricing | Key Features | |----------|------|----------|---------|-------------| | NextAuth / Auth.js | OSS library | Next.js apps wanting full control | Free | 80+ providers, DB adapters, self-hosted | | Clerk | Managed service | Fast launch, pre-built UI, user management | Free tier, then per-MAU | Drop-in components, user dashboard, org support | | Supabase Auth | Managed (part of Supabase) | Apps already using Supabase for DB/storage | Free tier, then per-MAU | Row-level security integration, magic links, SSO | | Lucia | OSS library | Full control, minimal abstraction | Free | Session-based, framework-agnostic, type-safe |
When to Use Each
- NextAuth / Auth.js: You want provider flexibility, self-hosting, and database session control. Best when you need custom flows.
- Clerk: You want auth done fast with pre-built UI components. Best for MVPs and teams that don't want to build auth UI.
- Supabase Auth: You're already using Supabase. Auth integrates with RLS policies for row-level security.
- Lucia: You want a minimal, type-safe session library without framework lock-in.
NextAuth.js Setup Pattern
// app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { prisma } from "@/lib/prisma";
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
GitHub({
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
}),
],
callbacks: {
session({ session, user }) {
session.user.id = user.id;
return session;
},
},
});
SECURITY_CHECKLIST
Before Shipping Auth
- [ ] Rate limiting: Login endpoint limited to 5-10 attempts per minute per IP.
- [ ] CSRF protection: Anti-CSRF tokens on all state-changing requests (or use
SameSite=Laxcookies). - [ ] Password hashing: Using bcrypt (cost 12+) or argon2id — never MD5, SHA-1, or plain SHA-256.
- [ ] HTTPS only: All auth endpoints served over TLS. Cookies have
Secureflag. - [ ] Input validation: Email format, password length (min 8, max 128), no SQL/NoSQL injection vectors.
- [ ] Account enumeration: Login and registration return the same response whether account exists or not.
- [ ] Session invalidation: Logout invalidates server-side session/refresh token, not just client cookie.
- [ ] MFA support: TOTP (authenticator app) or WebAuthn as second factor for sensitive accounts.
- [ ] Password reset: Time-limited tokens (1 hour), single-use, sent over secure channel.
- [ ] Audit logging: Log auth events (login, logout, failed attempts, password changes) with timestamp and IP.
Password Hashing
// Using bcrypt
import bcrypt from "bcrypt";
const SALT_ROUNDS = 12;
async function hashPassword(password: string): Promise {
return bcrypt.hash(password, SALT_ROUNDS);
}
async function verifyPassword(password: string, hash: string): Promise {
return bcrypt.compare(password, hash);
}
// Using argon2 (preferred for new projects)
import argon2 from "argon2";
async function hashPassword(password: string): Promise {
return argon2.hash(password, { type: argon2.argon2id });
}
async function verifyPassword(hash: string, password: string): Promise {
return argon2.verify(hash, password);
}
COMMON_MISTAKES
| Mistake | Risk | Fix | |---------|------|-----| | Storing JWT in localStorage | XSS can steal tokens | Use httpOnly cookies | | Long-lived JWTs (days/weeks) | Stolen token is valid for extended period | 15 min access token + refresh rotation | | Missing CSRF protection | Attackers can forge requests from other sites | SameSite=Lax cookies + CSRF token | | Weak password requirements | Brute force and credential stuffing | Min 8 chars, check against breached password lists | | Exposing user existence on login | Account enumeration | Generic "Invalid credentials" message | | Not rotating refresh tokens | Stolen refresh token grants indefinite access | Single-use refresh tokens with rotation | | Hardcoding secrets in source | Credential leak via git history | Use environment variables, never commit secrets | | Missing rate limiting on login | Brute force attacks | 5-10 attempts/min per IP, exponential backoff | | Rolling your own crypto | Subtle vulnerabilities | Use established libraries (bcrypt, argon2, jose) | | Not validating JWT claims | Token misuse across services | Always verify iss, aud, exp |
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: zebbern
- Source: zebbern/claude-code-guide
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.