jwt-security▌
mindrally/skills · updated Apr 22, 2026
You are an expert in JSON Web Token (JWT) security implementation. Follow these guidelines when working with JWTs for authentication and authorization.
JWT Security
You are an expert in JSON Web Token (JWT) security implementation. Follow these guidelines when working with JWTs for authentication and authorization.
Core Principles
- JWTs are not inherently secure - security depends on implementation
- Always validate tokens server-side, even for internal services
- Use asymmetric signing (RS256, ES256) when possible
- Keep tokens short-lived and implement proper refresh mechanisms
- Never store sensitive data in JWT payloads
Token Structure
A JWT consists of three parts: Header, Payload, and Signature.
header.payload.signature
Header Best Practices
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-identifier-for-rotation"
}
- Always include
kid(key ID) for key rotation support - Use
typ: "JWT"explicitly - Never accept
alg: "none"
Payload Best Practices
{
"iss": "https://auth.example.com",
"sub": "user-uuid-here",
"aud": "https://api.example.com",
"exp": 1704067200,
"iat": 1704063600,
"nbf": 1704063600,
"jti": "unique-token-id"
}
Required claims:
iss(issuer): Who created the tokensub(subject): Who the token representsaud(audience): Who the token is intended forexp(expiration): When the token expiresiat(issued at): When the token was created
Recommended claims:
nbf(not before): Token not valid before this timejti(JWT ID): Unique identifier for token revocation
Signing Algorithm Selection
Recommended: Asymmetric Algorithms
// RS256 - RSA with SHA-256 (most widely supported)
// ES256 - ECDSA with P-256 and SHA-256 (smaller keys)
// EdDSA - Edwards-curve Digital Signature Algorithm (most secure)
const ALLOWED_ALGORITHMS = ['RS256', 'ES256', 'EdDSA'];
When Symmetric is Required
// HS256 - HMAC with SHA-256
// Only use with a strong secret (minimum 256 bits / 32 bytes)
const secret = crypto.randomBytes(64).toString('hex');
Token Creation
Using RS256 (Recommended)
const jwt = require('jsonwebtoken');
const fs = require('fs');
const privateKey = fs.readFileSync('private.pem');
function createToken(userId, roles) {
const payload = {
sub: userId,
roles: roles,
// Keep custom claims minimal
};
const options = {
algorithm: 'RS256',
expiresIn: '15m', // Short-lived access tokens
issuer: 'https://auth.example.com',
audience: 'https://api.example.com',
keyid: 'current-key-id',
};
return jwt.sign(payload, privateKey, options);
}
Token Lifetime Guidelines
const TOKEN_LIFETIMES = {
accessToken: '15m', // 15 minutes max
refreshToken: '7d', // 7 days with rotation
idToken: '1h', // 1 hour
passwordReset: '15m', // 15 minutes
emailVerification: '24h', // 24 hours
};
Token Validation
Complete Validation Example
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');
// JWKS client for fetching public keys
const client = jwksClient({
jwksUri: 'https://auth.example.com/.well-known/jwks.json',
cache: true,
cacheMaxAge: 600000, // 10 minutes
rateLimit: true,
jwksRequestsPerMinute: 10,
});
async function validateToken(token) {
// 1. Decode header without verification to get kid
const decoded = jwt.decode(token, { complete: true });
if (!decoded) {
throw new Error('Invalid token format');
}
// 2. Validate algorithm against whitelist
if (!ALLOWED_ALGORITHMS.includes(decoded.header.alg)) {
throw new Error(`Algorithm ${decoded.header.alg} not allowed`);
}
// 3. Get signing key
const key = await client.getSigningKey(decoded.header.kid);
const publicKey = key.getPublicKey();
// 4. Verify signature and claims
const verified = jwt.verify(token, publicKey, {
algorithms: ALLOWED_ALGORITHMS, // Whitelist algorithms
issuer: 'https://auth.example.com',
audience: 'https://api.example.com',
clockTolerance: 30, // 30 seconds clock skew tolerance
});
return verified;
}
Validation Checklist
function validateTokenClaims(decoded) {
const now = Math.floor(Date.now() / 1000);
// 1. Check expiration
if (decoded.exp && decoded.exp < now) {
throw new Error('Token expired');
}
// 2. Check not before
if (decoded.nbf && decoded.nbf > now)Discussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.5★★★★★65 reviews- ★★★★★Liam Zhang· Dec 28, 2024
jwt-security fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
- ★★★★★Ganesh Mohane· Dec 20, 2024
jwt-security has been reliable in day-to-day use. Documentation quality is above average for community skills.
- ★★★★★Arjun Kapoor· Dec 16, 2024
Solid pick for teams standardizing on skills: jwt-security is focused, and the summary matches what you get after install.
- ★★★★★Arjun Jain· Dec 8, 2024
jwt-security is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Layla Martin· Dec 8, 2024
jwt-security has been reliable in day-to-day use. Documentation quality is above average for community skills.
- ★★★★★Layla Harris· Dec 4, 2024
I recommend jwt-security for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Kwame Brown· Dec 4, 2024
jwt-security reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Layla Yang· Nov 27, 2024
Keeps context tight: jwt-security is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Arya Jain· Nov 23, 2024
Useful defaults in jwt-security — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Chen Abebe· Nov 19, 2024
We added jwt-security from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
showing 1-10 of 65