Skip to main content

Authentication & RBAC: Secure Access Control Systems

00:04:00:26

Security First

Authentication and authorization are the foundation of application security. Get them wrong, and you expose user data and system resources. Get them right, and you build trust while protecting your platform.

Authentication Methods

Password-Based Authentication

Still the most common method:

  • Hashing: Use bcrypt, Argon2, or scrypt
  • Salt: Unique salt per password
  • Strength requirements: Enforce strong passwords
  • Password reset: Secure reset flow
  • Rate limiting: Prevent brute force attacks

OAuth 2.0 / OpenID Connect

Social login integration:

  • Google, GitHub, etc.: Popular providers
  • Authorization code flow: Most secure
  • PKCE: For mobile and SPAs
  • Token validation: Always verify tokens
  • User profile mapping: Handle provider differences

Multi-Factor Authentication (MFA)

Add an extra security layer:

  • TOTP: Time-based one-time passwords (Google Authenticator)
  • SMS OTP: One-time codes via SMS
  • Email OTP: Codes sent via email
  • Hardware tokens: YubiKey, etc.
  • Backup codes: For account recovery

JWT Implementation

Token Structure

JWTs consist of three parts:

  • Header: Algorithm and token type
  • Payload: Claims (user data)
  • Signature: Cryptographic signature

Best Practices

javascript
// Token generation
const token = jwt.sign(
  {
    userId: user.id,
    email: user.email,
    role: user.role
  },
  secretKey,
  {
    expiresIn: '15m', // Short-lived access token
    issuer: 'your-app',
    audience: 'your-app'
  }
);

// Refresh token (longer-lived, stored securely)
const refreshToken = jwt.sign(
  { userId: user.id, type: 'refresh' },
  refreshSecret,
  { expiresIn: '7d' }
);

Token Rotation

Implement refresh token rotation:

  1. Issue refresh token with access token
  2. Store refresh token securely (httpOnly cookie or database)
  3. Rotate on use: Issue new refresh token, invalidate old
  4. Detect theft: Multiple uses of same refresh token = compromise

Role-Based Access Control (RBAC)

Role Hierarchy

Design role structure:

  • Super Admin: Full system access
  • Admin: Manage users and content
  • Moderator: Content moderation
  • User: Standard user access
  • Guest: Limited read access

Permission System

Granular permissions:

javascript
const permissions = {
  'users:read': ['admin', 'moderator'],
  'users:write': ['admin'],
  'content:read': ['admin', 'moderator', 'user'],
  'content:write': ['admin', 'moderator'],
  'settings:read': ['admin'],
  'settings:write': ['admin']
};

const hasPermission = (user, permission) => {
  return permissions[permission]?.includes(user.role);
};

Implementation

javascript
// Middleware for route protection
const requirePermission = (permission) => {
  return (req, res, next) => {
    if (!hasPermission(req.user, permission)) {
      return res.status(403).json({ error: 'Forbidden' });
    }
    next();
  };
};

// Usage
app.get('/admin/users', 
  authenticate,
  requirePermission('users:read'),
  getUsers
);

Session Management

Session Storage

Choose storage method:

  • Database: Most control, requires cleanup
  • Redis: Fast, scalable, TTL support
  • JWT: Stateless, but harder to revoke
  • Cookies: Simple, but limited size

Security Considerations

  • HttpOnly cookies: Prevent XSS attacks
  • Secure flag: HTTPS only
  • SameSite: CSRF protection
  • Session timeout: Automatic expiration
  • Concurrent sessions: Limit or allow multiple

Password Security

Hashing

Never store plaintext passwords:

javascript
const bcrypt = require('bcrypt');

// Hash password
const hashedPassword = await bcrypt.hash(password, 12);

// Verify password
const isValid = await bcrypt.compare(password, hashedPassword);

Password Policies

Enforce strong passwords:

  • Minimum length: 8+ characters
  • Complexity: Mix of character types
  • Common passwords: Block common passwords
  • Password history: Prevent reuse
  • Expiration: Optional, often annoying

API Authentication

API Keys

For programmatic access:

  • Generate securely: Cryptographically random
  • Scope permissions: Limit what keys can do
  • Rate limiting: Prevent abuse
  • Rotation policy: Regular key rotation
  • Revocation: Ability to disable keys

Bearer Tokens

For user-initiated API access:

  • Short expiration: 15-60 minutes
  • Refresh tokens: For long-lived sessions
  • Token revocation: Ability to invalidate
  • Scope-based: Limit token permissions

Security Best Practices

Common Vulnerabilities

Protect against:

  • SQL Injection: Parameterized queries
  • XSS: Input sanitization
  • CSRF: Token validation
  • Session fixation: Regenerate on login
  • Timing attacks: Constant-time comparisons

Rate Limiting

Prevent abuse:

  • Login attempts: Limit failed logins
  • Password reset: Prevent enumeration
  • API calls: Rate limit endpoints
  • IP-based: Block suspicious IPs

Real-World Implementation

For a multi-tenant SaaS platform, I built:

  • JWT authentication: Access and refresh tokens
  • OAuth integration: Google, GitHub login
  • MFA support: TOTP and SMS OTP
  • RBAC system: Roles and permissions
  • Session management: Redis-based sessions
  • API authentication: API keys and bearer tokens
  • Rate limiting: Per-user and per-IP limits

Security features:

  • Password hashing: bcrypt with salt
  • Token rotation: Refresh token rotation
  • Audit logging: All auth events logged
  • Anomaly detection: Unusual login patterns
  • Account lockout: After failed attempts

Results:

  • Zero security breaches in production
  • 99.9% uptime for auth service
  • < 200ms average auth response time
  • Seamless user experience with SSO

Key Takeaways

  1. Never trust client input: Validate and sanitize everything
  2. Use established libraries: Don't roll your own crypto
  3. Implement defense in depth: Multiple security layers
  4. Monitor and log: Detect attacks early
  5. Keep dependencies updated: Security patches matter
  6. Test security: Regular security audits
  7. Document security: Security decisions need documentation

Authentication and authorization are complex, but following security best practices and using established patterns makes building secure systems achievable. The key is understanding threats and implementing appropriate defenses at every layer.