auth-patterns

auth-patterns

Use when implementing authentication. Use when storing passwords. Use when asked to store credentials insecurely.

4スター
0フォーク
更新日 1/23/2026
SKILL.md
readonlyread-only
name
auth-patterns
description

Use when implementing authentication. Use when storing passwords. Use when asked to store credentials insecurely.

Authentication Patterns

Overview

Never store plain passwords. Use proven auth patterns. Security is not optional.

Authentication is the front door to your system. Get it wrong and everything else is compromised.

When to Use

  • Implementing login/registration
  • Storing user credentials
  • Verifying user identity
  • Working with sessions or tokens

The Iron Rule

NEVER store passwords in plain text. ALWAYS use slow hashing.

No exceptions:

  • Not for "internal users only"
  • Not for "we'll encrypt later"
  • Not for "it's behind a firewall"
  • Not for "just for development"

Detection: Insecure Auth Smell

If passwords aren't properly hashed, STOP:

// ❌ VIOLATION: Plain text password
await db.users.create({
  email,
  password: password  // Stored as-is!
});

// ❌ VIOLATION: Fast hash (crackable)
const hashed = crypto.createHash('sha256').update(password).digest('hex');

// ❌ VIOLATION: Reversible encryption
const encrypted = encrypt(password, key);  // Can be decrypted!

The Correct Pattern: Bcrypt/Argon2

// ✅ CORRECT: Slow, salted hashing with bcrypt
import bcrypt from 'bcrypt';

const SALT_ROUNDS = 12;  // Adjust based on your hardware

async function hashPassword(plain: string): Promise<string> {
  return bcrypt.hash(plain, SALT_ROUNDS);
}

async function verifyPassword(plain: string, hashed: string): Promise<boolean> {
  return bcrypt.compare(plain, hashed);
}

// Registration
app.post('/register', async (req, res) => {
  const { email, password } = validated(req.body);
  
  const hashedPassword = await hashPassword(password);
  
  await db.users.create({
    email,
    password: hashedPassword  // Store the hash
  });
  
  res.status(201).json({ success: true });
});

// Login
app.post('/login', async (req, res) => {
  const { email, password } = validated(req.body);
  
  const user = await db.users.findByEmail(email);
  
  // Constant-time comparison to prevent timing attacks
  // Always verify even if user not found
  const dummyHash = '$2b$12$dummy.hash.here';
  const isValid = await verifyPassword(password, user?.password ?? dummyHash);
  
  if (!user || !isValid) {
    // Same error for both cases - prevents user enumeration
    return res.status(401).json({ error: 'Invalid credentials' });
  }
  
  const token = generateToken(user);
  res.json({ token });
});

Authentication Checklist

Password Storage

  • [ ] Use bcrypt or Argon2 (slow hash)
  • [ ] Salt rounds ≥ 12 for bcrypt
  • [ ] Never store plain text
  • [ ] Never use MD5/SHA1/SHA256 alone

Login Security

  • [ ] Constant-time comparison
  • [ ] Same error for "user not found" and "wrong password"
  • [ ] Rate limiting on login endpoint
  • [ ] Account lockout after N failures

Session/Token Security

  • [ ] JWTs: short expiry, secure secret
  • [ ] Sessions: secure, httpOnly cookies
  • [ ] Implement token refresh properly
  • [ ] Invalidate on logout/password change

Pressure Resistance Protocol

1. "We'll Encrypt Later"

Pressure: "Just store it for now, we'll add encryption"

Response: Plain text passwords get leaked. Breaches happen fast.

Action: Hash from day one. It's 3 lines of code.

2. "It's Behind a Firewall"

Pressure: "Internal network, no one can access it"

Response: Firewalls get breached. Insiders exist. Defense in depth.

Action: Hash regardless of network security.

3. "SHA256 Is Secure"

Pressure: "SHA256 is a strong hash"

Response: SHA256 is fast - billions per second on GPU. Bcrypt is intentionally slow.

Action: Use bcrypt or Argon2. Speed is the enemy.

4. "Just for Development"

Pressure: "Dev database doesn't need security"

Response: Dev code becomes prod code. Dev habits become prod habits.

Action: Use proper hashing in all environments.

Red Flags - STOP and Reconsider

  • password column without "hash" in name
  • Using crypto.createHash for passwords
  • Comparing passwords with ===
  • Same error messages reveal user existence
  • No rate limiting on auth endpoints

All of these mean: Fix the auth implementation.

Quick Reference

Insecure Secure
Plain text storage bcrypt/Argon2 hash
SHA256(password) bcrypt.hash(password, 12)
=== comparison bcrypt.compare()
"User not found" error "Invalid credentials"
Unlimited login attempts Rate limiting + lockout

Common Rationalizations (All Invalid)

Excuse Reality
"We'll encrypt later" Do it now. Takes 3 lines.
"Behind firewall" Defense in depth required.
"SHA256 is secure" Too fast. Use slow hashes.
"Just development" Dev becomes prod.
"Internal users only" Insiders cause breaches too.
"We trust our database" Databases get dumped.

The Bottom Line

Hash passwords with bcrypt. Use constant-time comparison. Return generic errors.

Password security is non-negotiable. Use slow hashes (bcrypt, Argon2). Prevent timing attacks. Don't leak user existence. Rate limit everything.

You Might Also Like

Related Skills

coding-agent

coding-agent

179Kdev-codegen

Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.

openclaw avataropenclaw
入手
add-uint-support

add-uint-support

97Kdev-codegen

Add unsigned integer (uint) type support to PyTorch operators by updating AT_DISPATCH macros. Use when adding support for uint16, uint32, uint64 types to operators, kernels, or when user mentions enabling unsigned types, barebones unsigned types, or uint support.

pytorch avatarpytorch
入手
at-dispatch-v2

at-dispatch-v2

97Kdev-codegen

Convert PyTorch AT_DISPATCH macros to AT_DISPATCH_V2 format in ATen C++ code. Use when porting AT_DISPATCH_ALL_TYPES_AND*, AT_DISPATCH_FLOATING_TYPES*, or other dispatch macros to the new v2 API. For ATen kernel files, CUDA kernels, and native operator implementations.

pytorch avatarpytorch
入手
skill-writer

skill-writer

97Kdev-codegen

Guide users through creating Agent Skills for Claude Code. Use when the user wants to create, write, author, or design a new Skill, or needs help with SKILL.md files, frontmatter, or skill structure.

pytorch avatarpytorch
入手

Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or constructors.

oven-sh avataroven-sh
入手

Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.

oven-sh avataroven-sh
入手