Ai auth-patterns

Authentication and authorization patterns — JWT, OAuth 2.0, sessions, RBAC/ABAC, password security, MFA, and vulnerability prevention. Use when implementing login flows, protecting routes, managing tokens, or auditing auth security.

install
source · Clone the upstream repo
git clone https://github.com/wpank/ai
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/wpank/ai "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/api/auth-patterns" ~/.claude/skills/wpank-ai-auth-patterns && rm -rf "$T"
manifest: skills/api/auth-patterns/SKILL.md
source content

Auth Patterns — Authentication & Authorization

SECURITY-CRITICAL SKILL — Auth is the front door. Get it wrong and nothing else matters.

Authentication Methods

MethodHow It WorksBest For
JWTSigned token sent with each requestSPAs, microservices, mobile APIs
Session-basedServer stores session, client holds cookieTraditional web apps, SSR
OAuth 2.0Delegated auth via authorization server"Login with Google/GitHub", API access
API KeysStatic key sent in headerInternal services, public APIs
Magic LinksOne-time login link via emailLow-friction onboarding, B2C
Passkeys/WebAuthnHardware/biometric challenge-responseHigh-security apps, passwordless

Installation

OpenClaw / Moltbot / Clawbot

npx clawhub@latest install auth-patterns

JWT Patterns

Dual-Token Strategy

Short-lived access token + long-lived refresh token:

Client → POST /auth/login → Server
Client ← { access_token, refresh_token }

Client → GET /api/data (Authorization: Bearer <access>) → Server
Client ← 401 Expired

Client → POST /auth/refresh { refresh_token } → Server
Client ← { new_access_token, rotated_refresh_token }

Token Structure

{
  "header": { "alg": "RS256", "typ": "JWT", "kid": "key-2024-01" },
  "payload": {
    "sub": "user_abc123",
    "iss": "https://auth.example.com",
    "aud": "https://api.example.com",
    "exp": 1700000900,
    "iat": 1700000000,
    "jti": "unique-token-id",
    "roles": ["user"],
    "scope": "read:profile write:profile"
  }
}

Signing Algorithms

AlgorithmTypeWhen to Use
RS256Asymmetric (RSA)Microservices — only auth server holds private key
ES256Asymmetric (ECDSA)Same as RS256, smaller keys and signatures
HS256SymmetricSingle-server apps — all verifiers share secret

Prefer RS256/ES256 in distributed systems.

Token Storage

StorageXSS SafeCSRF SafeRecommendation
httpOnly cookieYesNo (add CSRF token)Best for web apps
localStorageNoYesAvoid — XSS exposes tokens
In-memoryYesYesGood for SPAs, lost on refresh
Set-Cookie: access_token=eyJ...; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=900

Expiration Strategy

TokenLifetimeRotation
Access token5–15 minutesIssued on refresh
Refresh token7–30 daysRotate on every use
ID tokenMatch access tokenNot refreshed

OAuth 2.0 Flows

FlowClient TypeWhen to Use
Authorization Code + PKCEPublic (SPA, mobile)Default for all public clients
Authorization CodeConfidential (server)Server-rendered web apps with backend
Client CredentialsMachine-to-machineService-to-service, cron jobs
Device CodeInput-constrainedSmart TVs, IoT, CLI on headless servers

Implicit flow is deprecated. Always use Authorization Code + PKCE for public clients.

PKCE Flow

1. Client generates code_verifier (random 43-128 chars)
2. Client computes code_challenge = BASE64URL(SHA256(code_verifier))
3. Redirect to /authorize?code_challenge=...&code_challenge_method=S256
4. User authenticates, server redirects back with authorization code
5. Client exchanges code + code_verifier for tokens at /token
6. Server verifies SHA256(code_verifier) == code_challenge

Session Management

Server-Side Sessions

Client Cookie:  session_id=a1b2c3d4 (opaque, random, no user data)
Server Store:   { "a1b2c3d4": { userId: 123, roles: ["admin"], expiresAt: ... } }
StoreSpeedWhen to Use
RedisFastProduction default — TTL support, horizontal scaling
PostgreSQLModerateWhen Redis is overkill, need audit trail
In-memoryFastestDevelopment only

Session Security

ThreatPrevention
Session fixationRegenerate session ID after login
Session hijackinghttpOnly + Secure cookies, bind to IP/user-agent
CSRFSameSite cookies + CSRF tokens
Idle timeoutExpire after 15–30 min inactivity
Absolute timeoutForce re-auth after 8–24 hours

Authorization Patterns

PatternGranularityWhen to Use
RBACCoarse (admin, editor, viewer)Most apps — simple role hierarchy
ABACFine (attributes: dept, time, location)Enterprise — context-dependent access
Permission-basedMedium (post:create, user:delete)APIs — decouple permissions from roles
Policy-based (OPA/Cedar)FineMicroservices — externalized, auditable rules
ReBACFine (owner, member, shared-with)Social apps, Google Drive-style sharing

RBAC Implementation

const ROLE_PERMISSIONS: Record<string, string[]> = {
  admin:  ["user:read", "user:write", "user:delete", "post:read", "post:write", "post:delete"],
  editor: ["user:read", "post:read", "post:write"],
  viewer: ["user:read", "post:read"],
};

function requirePermission(permission: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    const permissions = ROLE_PERMISSIONS[req.user.role] ?? [];
    if (!permissions.includes(permission)) {
      return res.status(403).json({ error: "Forbidden" });
    }
    next();
  };
}

app.delete("/api/users/:id", requirePermission("user:delete"), deleteUser);

Password Security

AlgorithmRecommendedMemory-HardNotes
Argon2idFirst choiceYesResists GPU/ASIC attacks
bcryptYesNoBattle-tested, 72-byte limit
scryptYesYesGood alternative
PBKDF2AcceptableNoNIST approved, weaker vs GPU
SHA-256/MD5NeverNoNot password hashing

NIST 800-63B: Favor length (12+ chars) over complexity rules. Check against breached password lists. Don't force periodic rotation unless breach suspected.


Multi-Factor Authentication

FactorSecurityNotes
TOTP (Authenticator app)HighOffline-capable, Google Authenticator / Authy
WebAuthn/PasskeysHighestPhishing-resistant, hardware-backed
SMS OTPMediumVulnerable to SIM swap — avoid for high-security
Hardware keys (FIDO2)HighestYubiKey — best for admin accounts
Backup codesLow (fallback)One-time use, generate 10, store hashed

Security Headers

HeaderValue
Strict-Transport-Security
max-age=63072000; includeSubDomains; preload
Content-Security-PolicyRestrict script sources, no inline scripts
X-Content-Type-Options
nosniff
X-Frame-Options
DENY
Referrer-Policy
strict-origin-when-cross-origin
CORSWhitelist specific origins, never
*
with credentials

Common Vulnerabilities

#VulnerabilityPrevention
1Broken authenticationMFA, strong password policy, breach detection
2Session fixationRegenerate session ID on login
3JWT
alg:none
attack
Reject
none
, validate
alg
against allowlist
4JWT secret brute forceUse RS256/ES256, strong secrets (256+ bits)
5CSRFSameSite cookies, CSRF tokens
6Credential stuffingRate limiting, breached password check, MFA
7Insecure password storageArgon2id/bcrypt, never encrypt (hash instead)
8Insecure password resetSigned time-limited tokens, invalidate after use
9Open redirectValidate redirect URIs against allowlist
10Token leakage in URLSend tokens in headers or httpOnly cookies only
11Privilege escalationServer-side role checks on every request
12OAuth redirect_uri mismatchExact match redirect URI validation, no wildcards
13Timing attacksConstant-time comparison for secrets

NEVER Do

#RuleWhy
1NEVER store passwords in plaintext or reversible encryptionOne breach exposes every user
2NEVER put tokens in URLs or query parametersLogged by servers, proxies, referrer headers
3NEVER use
alg: none
or allow algorithm switching in JWTs
Attacker forges tokens
4NEVER trust client-side role/permission claimsUsers can modify any client-side value
5NEVER use MD5, SHA-1, or plain SHA-256 for password hashingNo salt, no work factor — cracked in seconds
6NEVER skip HTTPS in productionTokens and credentials sent in cleartext
7NEVER log tokens, passwords, or secretsLogs are broadly accessible and retained
8NEVER use long-lived tokens without rotationA single leak grants indefinite access
9NEVER implement your own cryptoUse established libraries — jose, bcrypt, passport
10NEVER return different errors for "user not found" vs "wrong password"Enables user enumeration