Skip to main content
Career Paths
Concepts
Fsp Security Auth Encryption
The Simplified Tech

Role-based learning paths to help you master cloud engineering with clarity and confidence.

Product

  • Career Paths
  • Interview Prep
  • Scenarios
  • AI Features
  • Cloud Comparison
  • Resume Builder
  • Pricing

Community

  • Join Discord

Account

  • Dashboard
  • Credits
  • Updates
  • Sign in
  • Sign up
  • Contact Support

Stay updated

Get the latest learning tips and updates. No spam, ever.

Terms of ServicePrivacy Policy

© 2026 TheSimplifiedTech. All rights reserved.

BackBack
Interactive Explainer

Security: Authentication, Authorization & Encryption

JWT deep-dive, OAuth 2.0 flows, RBAC vs ABAC, OWASP Top 10 vulnerabilities, encryption at rest and in transit.

🎯Key Takeaways
Design security in from the start — retrofitting is expensive and incomplete
JWTs: explicit algorithm whitelist, short expiry (15min), HttpOnly cookies for refresh tokens
RBAC for coarse-grained access + row-level security for resource ownership
OWASP: parameterize all queries, verify ownership, use bcrypt for passwords
Encryption: TLS everywhere in transit; AES-256-GCM + envelope encryption at rest
Secrets management: AWS Secrets Manager / Vault — never hardcode, never commit

Security: Authentication, Authorization & Encryption

JWT deep-dive, OAuth 2.0 flows, RBAC vs ABAC, OWASP Top 10 vulnerabilities, encryption at rest and in transit.

~4 min read
Be the first to complete!
What you'll learn
  • Design security in from the start — retrofitting is expensive and incomplete
  • JWTs: explicit algorithm whitelist, short expiry (15min), HttpOnly cookies for refresh tokens
  • RBAC for coarse-grained access + row-level security for resource ownership
  • OWASP: parameterize all queries, verify ownership, use bcrypt for passwords
  • Encryption: TLS everywhere in transit; AES-256-GCM + envelope encryption at rest
  • Secrets management: AWS Secrets Manager / Vault — never hardcode, never commit

Lesson outline

Security is a property, not a feature

Security cannot be added after the fact. Retrofitting security onto an insecure system is like adding foundations to an already-built house — enormously expensive and never quite right.

The 2017 Equifax breach exposed 147 million records via an unpatched 6-month-old vulnerability. A 2-minute fix prevented — a $575M settlement did not.

Threat modeling before implementation

Ask: "Who are my adversaries? What are they trying to do? What is the impact? What is the prevention cost?" Checklists help but cannot replace this thinking.

JWT: how they work and where they fail

JWT = header.payload.signature (base64url). The signature prevents tampering without the secret key. The server verifies the signature — if valid, trusts the payload.

Algorithm confusion attack: If your server accepts `alg: none`, an attacker removes the signature and the token is accepted. Always explicitly whitelist the algorithm.

Revocation problem: JWTs are valid until expiry — cannot be invalidated without a blocklist (negates stateless benefit). Solution: short expiry (15 min) + revocable refresh tokens.

HS256 vs RS256: HS256 uses one shared secret (sign and verify). RS256 uses private key (sign) + public key (verify). Use RS256 when multiple services verify tokens.

jwt-auth-secure.ts
1import jwt from 'jsonwebtoken';
2
3function generateTokenPair(userId: string, roles: string[]) {
4 const accessToken = jwt.sign(
5 { sub: userId, roles, type: 'access' },
6 process.env.JWT_SECRET!,
7 {
8 algorithm: 'HS256', // Explicitly set — never allow 'none'
ALWAYS explicitly set algorithm — never let the token specify its own
9 expiresIn: '15m', // Short-lived access token
10 issuer: 'api.example.com', // Prevents reuse from other services
11 audience: 'app.example.com',
12 }
13 );
14
15 // Refresh token: opaque random string stored in DB (revocable)
16 const refreshToken = crypto.randomBytes(32).toString('hex');
17 return { accessToken, refreshToken };
18}
19
20async function verifyAccessToken(token: string) {
Explicit algorithm whitelist prevents algorithm confusion attacks
21 const payload = jwt.verify(token, process.env.JWT_SECRET!, {
22 algorithms: ['HS256'], // ← Explicit whitelist — critical
23 issuer: 'api.example.com',
24 audience: 'app.example.com',
25 });
26
27 // Optional: check revocation list for compromised tokens
28 const jti = (payload as jwt.JwtPayload).jti;
29 if (jti && await redis.exists(`revoked:${jti}`)) {
30 throw new Error('Token revoked');
31 }
32
33 return payload as jwt.JwtPayload;
localStorage is readable by XSS; HttpOnly cookies are not
34}
35
36// Store access token: memory/session storage (not localStorage — XSS risk)
37// Store refresh token: HttpOnly cookie (inaccessible from JS)

RBAC vs ABAC: authorization at scale

RBAC: Users have roles, roles have permissions. Simple. Fails for "user can only edit their own documents."

ABAC: Policies use attributes of user, resource, action, environment. Flexible but complex.

ReBAC: Permissions based on relationships (user is member of team, team has access to project). Used by Google Docs, GitHub, Notion. Best for multi-tenant collaborative apps.

In practice: start with RBAC. Add row-level ownership checks. Graduate to ReBAC only when RBAC becomes unmanageable.

authorization.ts
1// RBAC + Row-Level Security (covers 90% of use cases)
2
3type Role = 'admin' | 'editor' | 'viewer';
4type Permission = 'read' | 'write' | 'delete' | 'manage_users';
5
6const ROLE_PERMISSIONS: Record<Role, Permission[]> = {
7 admin: ['read', 'write', 'delete', 'manage_users'],
8 editor: ['read', 'write'],
9 viewer: ['read'],
10};
11
12// RBAC: coarse-grained role check
RBAC check is O(1) — fast enough to run on every request
13function can(user: User, permission: Permission): boolean {
14 return ROLE_PERMISSIONS[user.role]?.includes(permission) ?? false;
15}
16
17// Row-level: verify resource ownership (ALWAYS required alongside RBAC)
Row-level security: NEVER skip ownership verification
18async function canEditDocument(userId: string, documentId: string) {
19 const doc = await db.query.documents.findFirst({
20 where: eq(documents.id, documentId),
21 columns: { ownerId: true, orgId: true },
22 });
23 if (doc?.ownerId === userId) return true; // Owner can always edit
24
25 const user = await db.query.users.findFirst({ where: eq(users.id, userId) });
26 // Admin in same org can edit
27 if (user?.role === 'admin' && user?.orgId === doc?.orgId) return true;
28 return false;
29}
30
31// Authorization middleware
32function requirePermission(permission: Permission) {
33 return async (req: Request, res: Response, next: NextFunction) => {
34 if (!req.user) return res.status(401).json({ error: 'Unauthorized' });
35 if (!can(req.user, permission)) {
36 return res.status(403).json({ error: 'Forbidden' });
37 }
38 next();
39 };
40}

OWASP Top 10: the most critical vulnerabilities

  • 💉Injection (SQL, Command) — Never concatenate user input into queries. Always use parameterized queries/ORM.
  • 🔓Broken Access Control (IDOR) — Verify resource ownership on every request. UUID IDs prevent enumeration.
  • 🔑Cryptographic Failures — MD5/SHA1 broken for passwords. Use bcrypt/argon2. HTTPS everywhere. Encrypt PII at rest.
  • ⚙️Security Misconfiguration — Default credentials, verbose errors, open S3 buckets, permissive CORS.
  • 🌐XSS — Sanitize all user output. Use Content Security Policy (CSP) headers.
  • 🔄SSRF — Validate and allowlist URLs before server-side fetch.

Three security questions for every PR

Is user input sanitized? Is resource ownership verified? Are credentials stored securely? These three questions catch the majority of OWASP Top 10 vulnerabilities.

Encryption: in transit and at rest

In transit: TLS 1.3 for all external traffic. mTLS for internal service-to-service. Never HTTP — even internal networks can be compromised.

At rest: Encrypt sensitive DB columns (PII, payment tokens) with AES-256-GCM. Use envelope encryption: a data key (DEK) encrypts data; a key encryption key (KEK) from KMS encrypts the DEK. Rotate KEK without re-encrypting all data.

Password hashing: bcrypt (cost factor 12+) or argon2id. Never MD5, SHA1, or SHA256 for passwords — designed for speed. A modern GPU tries 10 billion SHA256 hashes/second; bcrypt limits to ~100/second.

Secrets management: Never hardcode secrets or commit .env files. Use AWS Secrets Manager, HashiCorp Vault, or GCP Secret Manager. Rotate automatically.

How this might come up in interviews

Security interviews test threat modeling, not tool memorization.

Common questions:

  • How do JWTs work and what are their security pitfalls?
  • What is IDOR and how do you prevent it?
  • How would you store passwords securely?
  • Design auth for a multi-tenant SaaS application.

Strong answers include:

  • Mentions algorithm confusion attacks for JWT
  • Chooses bcrypt over SHA256 for passwords
  • Verifies resource ownership beyond authentication
  • Knows the difference between OAuth 2.0 and OIDC

Red flags:

  • Stores tokens in localStorage
  • Uses MD5 for passwords
  • Does not verify resource ownership
  • Cannot explain RBAC vs ABAC

Quick check · Security: Authentication, Authorization & Encryption

1 / 1

A JWT has `"alg": "none"` in its header. What should your server do?

Key takeaways

  • Design security in from the start — retrofitting is expensive and incomplete
  • JWTs: explicit algorithm whitelist, short expiry (15min), HttpOnly cookies for refresh tokens
  • RBAC for coarse-grained access + row-level security for resource ownership
  • OWASP: parameterize all queries, verify ownership, use bcrypt for passwords
  • Encryption: TLS everywhere in transit; AES-256-GCM + envelope encryption at rest
  • Secrets management: AWS Secrets Manager / Vault — never hardcode, never commit

From the books

The Web Application Hacker's Handbook — Stuttard and Pinto (2011)

Chapter 8: Attacking Access Controls

Understanding how attackers exploit vulnerabilities is the fastest way to design defenses that work. Read this book to understand what you are defending against.

Ready to see how this works in the cloud?

Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.

View role-based paths

Sign in to track your progress and mark lessons complete.

Discussion

Questions? Discuss in the community or start a thread below.

Join Discord

In-app Q&A

Sign in to start or join a thread.