This article provides a critical security checklist for startups, emphasizing that security is a foundational architectural concern, not an afterthought. It deeply explores authentication and access control strategies, offering trade-offs for different approaches like full-service platforms, OAuth 2.0 with frameworks, and a hybrid model using delegated login with in-house session management. The discussion highlights the importance of choosing an authentication architecture that scales and integrates well with future distributed systems.
Read original on Dev.to #systemdesignMany startups defer security implementation, viewing it as a feature to be added later. However, the article strongly argues that security is a fundamental architectural layer. Retrofitting security becomes exponentially more expensive and complex as a system grows, potentially leading to significant data breach costs that can cripple a nascent company. Early architectural decisions around security are crucial for long-term stability and scalability.
The choice of authentication mechanism is one of the most impactful security decisions. The article outlines three primary architectural options, each with distinct trade-offs regarding development speed, flexibility, vendor lock-in, and scalability.
// Example: After OAuth 2.0 callback, issue your own tokens
import { sign, verify } from "jsonwebtoken";
// Short-lived access token (15 min)
const accessToken = sign(
{ userId: user.id, role: user.role },
process.env.JWT_SECRET ?? "",
{ expiresIn: "15m", issuer: "your-app", audience: "your-api" },
);
// Longer-lived refresh token (7 days), stored in DB for revocation
const refreshToken = sign(
{ userId: user.id, tokenVersion: user.tokenVersion },
process.env.REFRESH_SECRET ?? "",
{ expiresIn: "7d" },
);
// Set as HTTP-only cookies (not accessible via JavaScript = XSS resistant)
res.cookie("access_token", accessToken, {
httpOnly: true,
secure: true,
sameSite: "strict",
maxAge: 15 * 60 * 1000,
});JWT Token Security Best Practices
For web applications, prefer HTTP-only, Secure, and SameSite:Strict cookies for JWT storage over localStorage. This significantly reduces XSS attack vectors. For mobile, use secure platform-specific storage for bearer tokens retrieved from a dedicated API endpoint. Your API should validate both types of tokens.