Skip to content
Back to skills

Authentication Best Practices

ASecurity

Use when Authentication and Authorization mastery. Best practices for OAuth2, OpenID Connect, JWT (JSON Web Tokens), session management, password hashing, MFA (Multi-Factor Authentication), RBAC/ABAC, SSO, and secure credential storage. Use when auditing or implementing login flows, identity systems, or access control.

  • 5 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 27, 2026
ai-agentstypescriptgobashnextjsgitapibackendsecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 27, 2026

npx -y skills add Harmitx7/tribunal-kit --skill authentication-best-practices --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Authentication Best Practices?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Authentication Best Practices
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/harmitx7-authentication-best-practices-tribunal-kit/badge)](https://www.skillsdirectory.com/skills/harmitx7-authentication-best-practices-tribunal-kit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: authentication-best-practices
description: "Use when Authentication and Authorization mastery. Best practices for OAuth2, OpenID Connect, JWT (JSON Web Tokens), session management, password hashing, MFA (Multi-Factor Authentication), RBAC/ABAC, SSO, and secure credential storage. Use when auditing or implementing login flows, identity systems, or access control."
version: 5.0.0
last-updated: 2026-09-13
skills:
  - backend-security-expert
  - api-security-auditor
  - vulnerability-scanner
tools: Read, Grep, Glob, Bash, Edit, Write
scripts-binding:
  - .agent/scripts/lint_runner.js
  - .agent/scripts/verify_all.js
---

# Authentication & Authorization β€” Identity Mastery

---

## πŸ› οΈ Technical Architecture & Reference Recipes

---

---

## Passwords & Hashing

```typescript
// ❌ BAD: md5, sha1, sha256 (too fast, vulnerable to brute force/rainbow tables)
const hash = crypto.createHash('sha256').update(password).digest('hex');

// βœ… GOOD: Argon2 (memory-hard, ASIC resistant) or bcrypt
import * as argon2 from 'argon2';

async function hashPassword(password: string): Promise<string> {
  // Argon2 hashes include the salt inherently in the resulting string
  return await argon2.hash(password, {
    type: argon2.argon2id, // recommended variant
    memoryCost: 2 ** 16, // 64 MB
    timeCost: 3, // iterations
    parallelism: 1, // threads
  });
}

async function verifyPassword(hash: string, password: string): Promise<boolean> {
  return await argon2.verify(hash, password);
}
```

### Password Policies

- **Length over complexity**: Require minimum 12 characters. Stop requiring arbitrary symbols (e.g., `!@#`).
- **Check against breaches**: Use HaveIBeenPwned API or similar to reject compromised passwords during signup.
- **Never expire passwords arbitrarily**: Only force resets if there is evidence of a breach.

---

## Session Management vs. JWT

### 1. Stateful Sessions (Cookies)

**Best for**: Monolithic web apps, SSR apps (Next.js, Remix).

- Server stores session ID mapped to user data in Redis/DB.
- Client stores session ID in an `HttpOnly`, `Secure`, `SameSite=Lax/Strict` cookie.
- **Pros**: Immediate revocation, server-side truth, invisible to XSS.
- **Cons**: Requires DB lookup per request.

### 2. Stateless JWT (JSON Web Tokens)

**Best for**: Distributed APIs, Microservices, Native mobile apps.

- Server signs a token containing user claims.
- Client passes it in `Authorization: Bearer <token>` header.
- **Pros**: No DB lookup needed, easy cross-origin sharing.
- **Cons**: Cannot be easily revoked before expiration.

### The JWT "Refresh Token" Pattern

```typescript
// Scenario: API authentication
// 1. Access Token (Short-lived: 15 mins)
const accessToken = jwt.sign({ userId: user.id }, JWT_SECRET, {
  expiresIn: '15m',
  algorithm: 'HS256', // ALWAYS explicitly specify
});
// 2. Refresh Token (Long-lived: 7 days, opaque string in DB)
const refreshToken = crypto.randomBytes(40).toString('hex');
await db.refreshTokens.create({ token: refreshToken, userId: user.id, expires: addDays(7) });

// Client flow:
// - Access token kept in memory (JS variable) to prevent XSS theft.
// - Refresh token kept in HttpOnly cookie.
// - When Access Token expires, endpoint reads cookie, validates DB, issues new Access Token.
```

---

## OAuth2 & OIDC (OpenID Connect)

```
Roles:
1. Resource Owner (User)
2. Client (Your App)
3. Authorization Server (Google/GitHub/Auth0)
4. Resource Server (API)

Flow (Authorization Code + PKCE):
1. User clicks "Login with Google".
2. App generates `code_verifier` and `code_challenge`.
3. App redirects user to Google with `code_challenge`.
4. User logs in, Google redirects back to App with an authorization `code`.
5. App sends `code` + `code_verifier` to Google backend.
6. Google returns `id_token` (OIDC identity) and `access_token` (OAuth permissions).

// ❌ HALLUCINATION TRAP: Implicit Flow is deprecated.
// Never use Implicit Flow (response_type=token) where the token is returned in the URL hash.
// Always use Authorization Code Flow with PKCE, even for Single Page Apps (SPAs).
```

---

## Multi-Factor Authentication (MFA)

- **SMS**: Deprecated by NIST due to SIM swapping vulnerabilities. (Better than nothing, but avoid as primary MFA).
- **TOTP (Authenticator Apps)**: Standard implementations use HMAC-SHA1. Keep the secret key heavily encrypted at rest.
- **WebAuthn / Passkeys**: The modern gold standard. Replaces passwords entirely using hardware enclaves (FaceID, TouchID, YubiKey).

---

## Authorization Models

### RBAC (Role-Based Access Control)

- Users have Roles (`admin`, `editor`, `viewer`).
- Roles have Permissions (`create:post`, `delete:user`).

```typescript
// βœ… Check permissions, not roles directly (more flexible)
if (!user.permissions.includes('delete:user')) {
  throw new ForbiddenError();
}
```

### ABAC (Attribute-Based Access Control)

- Access based on context (e.g., "User can edit Document if Document.department == User.department").

```typescript
// Example Policy
function canEditPost(user: User, post: Post): boolean {
  if (user.role === 'admin') return true;
  if (post.authorId === user.id) return true;
  if (post.status === 'draft' && user.department === 'content') return true;
  return false;
}
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…