analyzing-projects
Analyzes codebases to understand structure, tech stack, patterns, and conventions. Use when…
Implements authentication, authorization, encryption, secrets management, and security hardening patterns. Use when designing auth flows, managing secrets, configuring CORS, implementing rate limiting, or when asked about JWT, OAuth, password hashing, API keys, RBAC, or security
$ npx -y skills add CloudAI-X/claude-workflow-v2 --skill security-patterns --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/security-patternsContext preview
The summary Claude sees to decide when to auto-load this skill.
Implements authentication, authorization, encryption, secrets management, and security hardening patterns. Use when designing auth flows, managing secrets, configuring CORS, implementing rate limiting, or when asked about JWT, OAuth, password hashing, API keys, RBAC, or security
name: security-patterns description: Implements authentication, authorization, encryption, secrets management, and security hardening patterns. Use when designing auth flows, managing secrets, configuring CORS, implementing rate limiting, or when asked about JWT, OAuth, password hashing, API keys, RBAC, or security best practices.
Copy this checklist and track progress:
Security Implementation Progress: - [ ] Step 1: Choose authentication strategy - [ ] Step 2: Implement authorization model - [ ] Step 3: Set up password hashing - [ ] Step 4: Configure secrets management - [ ] Step 5: Enable encryption (transit + rest) - [ ] Step 6: Configure CORS - [ ] Step 7: Add rate limiting - [ ] Step 8: Validate against anti-patterns checklist
import jwt from "jsonwebtoken";
function generateTokens(user: User) {
const accessToken = jwt.sign(
{ sub: user.id, role: user.role },
process.env.JWT_SECRET!,
{ expiresIn: "15m", algorithm: "HS256" },
);
const refreshToken = jwt.sign(
{ sub: user.id, tokenVersion: user.tokenVersion },
process.env.JWT_REFRESH_SECRET!,
{ expiresIn: "7d" },
);
return { accessToken, refreshToken };
}
// WRONG: localStorage (XSS vulnerable) | CORRECT: httpOnly cookie for refresh, memory for access
res.cookie("refreshToken", refreshToken, {
httpOnly: true,
secure: true,
sameSite: "strict",
maxAge: 7 * 24 * 60 * 60 * 1000,
path: "/api/auth/refresh",
});function authenticate(req: Request, res: Response, next: NextFunction) {
const header = req.headers.authorization;
if (!header?.startsWith("Bearer ")) {
return res.status(401).json({ error: "Missing token" });
}
try {
const token = header.slice(7);
const payload = jwt.verify(token, process.env.JWT_SECRET!, {
algorithms: ["HS256"], // pin: never let the token choose its algorithm
}) as JwtPayload;
req.user = { id: payload.sub, role: payload.role };
next();
} catch (err) {
if (err instanceof jwt.TokenExpiredError) {
return res.status(401).json({ error: "Token expired" });
}
return res.status(401).json({ error: "Invalid token" });
}
}import session from "express-session";
import { RedisStore } from "connect-redis";
app.use(
session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET!,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "strict",
maxAge: 24 * 60 * 60 * 1000, // 24 hours
},
}),
);Authorization Code Flow with PKCE (all clients): 1. Redirect to provider: /authorize?response_type=code&client_id=...&redirect_uri=...&scope=openid email &state=RANDOM&nonce=RANDOM&code_challenge=...&code_challenge_method=S256 2. User authenticates, provider redirects back with ?code=AUTHORIZATION_CODE&state=... (reject if state differs) 3. Backend exchanges code for tokens (POST /token with code_verifier, plus client_secret for confidential clients) 4. Backend validates the id_token (signature, iss, aud, exp, nonce), then creates session/JWT Public clients (SPAs, mobile): same flow without client_secret NEVER use Implicit Flow (deprecated, tokens exposed in URL)
async function authenticateApiKey(
req: Request,
res: Response,
next: NextFunction,
) {
const apiKey = req.headers["x-api-key"] as string;
if (!apiKey) return res.status(401).json({ error: "API key required" });
// WRONG: Direct comparison (timing attack) | CORRECT: Hash-based lookup
const hashedKey = crypto.createHash("sha256").update(apiKey).digest("hex");
const keyRecord = await db.apiKey.findUnique({ where: { hash: hashedKey } });
if (!keyRecord || keyRecord.revokedAt)
return res.status(401).json({ error: "Invalid API key" });
req.apiClient = { id: keyRecord.clientId, scopes: keyRecord.scopes };
next();
}const PERMISSIONS = {
admin: [
"users:read",
"users:write",
"users:delete",
"posts:read",
"posts:write",
"posts:delete",
],
editor: ["posts:read", "posts:write", "posts:delete", "users:read"],
viewer: ["posts:read", "users:read"],
} as const;
type Role = keyof typeof PERMISSIONS;
function authorize(...requiredPermissions: string[]) {
return (req: Request, res: Response, next: NextFunction) => {
const userPermissions = PERMISSIONS[req.user.role as Role] || [];
const hasPermission = requiredPermissions.every((p) =>
(userPermissions as readonly string[]).includes(p),
);
if (!hasPermission)
return res.status(403).json({ error: "Insufficient permissions" });
next();
};
}
// Usage: app.delete("/api/users/:id", authenticate, authorize("users:delete"), deleteUser);// WRONG: Only checking role, not ownership -- any editor can edit ANY post
// CORRECT: Check ownership or admin role
app.put(
"/api/posts/:id",
authenticate,
authorize("posts:write"),
async (req, res) => {
const post = await db.post.findUnique({ where: { id: req.params.id } });
if (!post) return res.status(404).json({ error: "Not found" });
if (post.authorId !== req.user.id && req.user.role !== "admin") {
return res
.status(403)
.json({ error: "Not authorized to edit this post" });
}
// WRONG: data: req.body -- mass assignment lets the client overwrite authorId
constA universal Claude Code workflow plugin with specialized agents, skills, hooks, and mode commands for any software project. Compatible with skills.sh — works with Claude Code, Cursor, Codex, and 35+ AI agents.
Repo: CloudAI-X/claude-workflow-v2
Analyzes codebases to understand structure, tech stack, patterns, and conventions. Use when…
Convex backend development guidelines. Use when writing Convex functions, schemas, queries,…
Designs database schemas, indexing strategies, query optimization, and migration patterns for…
Designs REST and GraphQL APIs including endpoints, error handling, versioning, and…
Designs software architecture and selects appropriate patterns for projects. Use when…
Designs and implements testing strategies for any codebase. Use when adding tests, improving…