Skip to content
Development
Skill

/secure-auth

Implement authentication securely — authentication vs authorization, password hashing (argon2id/bcrypt), sessions vs JWT (storage, expiry, refresh, revocation), MFA, OAuth2/OIDC flows, and defenses against credential stuffing, session fixation, and CSRF. Worked examples + a

From plugin
skills
917 skills54 agents

Claude Code

$ npx -y skills add vanara-agents/skills --skill secure-auth --agent claude-code

SKILL.md

secure-auth.SKILL.md
name: secure-auth
description: Implement authentication securely — authentication vs authorization, password hashing (argon2id/bcrypt), sessions vs JWT (storage, expiry, refresh, revocation), MFA, OAuth2/OIDC flows, and defenses against credential stuffing, session fixation, and CSRF. Worked examples + a runnable password-policy check.
type: skill
version: 2.0.0
updated: 2026-06-29

Secure Authentication

Authentication is the front door to your system, and it is the single control attackers probe hardest. The goal of this skill is **not** to teach you to invent a clever scheme — it is to help you assemble well-understood primitives correctly, because almost every real-world breach in this area comes from a broken assembly of good parts, not from cracked cryptography. Heavy detail lives in `references/`; copy-paste material in `examples/`; a runnable policy check in `scripts/`.

Mental model

Three distinct questions get muddled constantly. Keep them separate:

| Question | Concern | Wrong answer looks like | |---|---|---| | Who are you? | **Authentication** (login, password, MFA) | trusting a client-supplied `user_id` | | What may you do? | **Authorization** (roles, ownership, scopes) | checking auth but not ownership (IDOR) | | How do we remember you? | **Session management** (cookies/tokens) | long-lived tokens you can't revoke |

A request can be perfectly *authenticated* and still be an attack if you skip *authorization*. The most common API vulnerability — Broken Object Level Authorization — is exactly this: a logged-in user reads `/accounts/124` when they only own `124`'s neighbor. Always check ownership server-side, never trust an identifier the client could change.

1. Password storage: slow hash, never plaintext

The non-negotiable rule: **never store a recoverable password.** Store a one-way hash produced by a *deliberately slow* algorithm so that a stolen database is expensive to crack offline.

import argon2 from 'argon2';

// Registration / password change — argon2id is the current default recommendation.
const hash = await argon2.hash(password, { type: argon2.argon2id });
// Store `hash` (it embeds the salt + cost params). NEVER store `password`.

// Login — constant-time verify; argon2 reads cost params from the stored hash.
const ok = await argon2.verify(hash, attempt);

Use **argon2id** (preferred) or **bcrypt** (battle-tested, fine if argon2 isn't available). Never use fast general-purpose hashes (`MD5`, `SHA-256`) — a GPU computes billions of those per second, so a leak becomes a mass account takeover within hours. Always salt (argon2/bcrypt do this for you), and validate the password against a policy and a breached-password list *before* hashing — run `scripts/check-password-policy.mjs --selftest` to see the kind of check that belongs at this boundary. The full parameter-tuning guidance is in [references/password-hashing.md](references/password-hashing.md).

2. Sessions vs JWT: how you remember a logged-in user

Two dominant models, with a real trade-off around **revocation**:

  • **Server-side sessions** — a random opaque session ID in an `HttpOnly; Secure; SameSite` cookie; state

lives server-side (DB/Redis). Revocation is trivial: delete the row. This is the safe default for classic web apps.

  • **Stateless JWTs** — a signed token the client carries. Scales without shared session storage, but you

**cannot un-issue a signed token** before it expires. Mitigate with short-lived access tokens (5–15 min) plus a revocable, rotating refresh token kept server-side.

Set-Cookie: session=9f2c...; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600

Storage matters enormously: a token in `localStorage` is readable by any XSS payload, so prefer `HttpOnly` cookies (which JavaScript cannot read) over web storage for anything that authenticates a request. The complete comparison — expiry, refresh rotation, reuse detection, and revocation strategies — is in [references/sessions-vs-jwt.md](references/sessions-vs-jwt.md).

3. MFA and step-up

A password alone is a single point of failure against phishing and credential stuffing. Offer a second factor and require it for sensitive actions (password change, payouts):

  • **TOTP** (authenticator app) — good baseline, phishable but cheap.
  • **WebAuthn / passkeys** — phishing-resistant, hardware-backed; prefer where you can.
  • **SMS** — weakest (SIM-swap), use only as a fallback.

Treat MFA as *step-up*: don't force it on every request, escalate it when risk rises.

4. OAuth2 / OIDC: delegated auth done right

When you offload login to a provider (Google, an identity platform), use **OAuth2 Authorization Code flow with PKCE** for web and mobile/SPA clients. Do not use the implicit flow (deprecated) and never the resource-owner password flow for third-party login. OIDC layers an identity `id_token` on top of OAuth2's access token. Validate the `id_token` signature, `iss`, `aud`, and `exp`, and use the `state` parameter to defend against CSRF on the callback. See [references/oauth2-oidc.md](references/oauth2-oidc.md) for the full flow diagrams and validation checklist, and `examples/auth-flow.md` for an annotated walk-through.

5. Account recovery

Recovery flows are a favorite bypass — they are authentication's back door. Make reset tokens **single-use, time-limited (e.g. 15–30 min), and high-entropy**, store only their hash, and invalidate all active sessions on a successful reset. Critically, return the **same response** whether or not the email exists, and keep timing uniform, so the endpoint can't be used to enumerate accounts.

Common pitfalls (failure modes)

  • **Fast/unsalted hashes** (`SHA-256`, `MD5`) — instantly crackable at scale after a DB leak.
  • **JWT you can't revoke** — a long-lived access token stays valid after logout/compromise; keep them short.
  • **Tokens in `localStorage`** — any XSS exfiltrates them; use `HttpOnly` cookies.
  • **Session fixation** — not rotatin
Read more
@vanara-agents
Ships withskills

🐒 Free agents, skills & packs for Claude Code One subscription. An army of Claude Code agents. 30 production-grade agents, skills, and packs for Claude Code — free, Apache-2.0, install with one command.

917 skills54 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
9
Star history of vanara-agents/skills on GitHub, a chart by star-history.com

Other skills on skills.

api-pagination

api-pagination

Implement correct, fast API pagination — cursor vs offset trade-offs, opaque cursor encoding, stable sort keys, page-size limits,…

caching-strategies

caching-strategies

Deep reference for caching — what to cache, cache-aside vs read/write-through/write-behind, TTLs with jitter, eviction…

conventional-commits

conventional-commits

Write Conventional Commits — the type(scope)!: subject + body + footer spec — so history is readable and changelogs and SemVer…

database-migrations

database-migrations

How to write safe, reversible, zero-downtime database schema migrations — additive-first changes, the expand/migrate/contract…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about secure-auth.

Which coding agents can use secure-auth?
secure-auth installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.