Feature Flag Service Tutorial · Module 09 of 10

Security & Compliance

Add authentication (JWT, OAuth), authorization (RBAC), audit logging for all flag changes, data encryption, and compliance documentation. Support API keys for SDKs. By the end, the service meets enterprise security requirements.

~4–5 hrsAdvancedSecurity focus
← Back to Module 09 overview
What You'll Have at the End

Definition of Done

  • JWT authentication: API validates tokens on all protected routes.
  • API keys: SDKs can use static API keys instead of JWT.
  • RBAC: Admin (create/delete flags), Editor (modify flags), Viewer (read only).
  • Audit logging: Every flag change logged with user, timestamp, old/new values.
  • Secrets management: API keys stored hashed, never in logs.
  • Encryption: Sensitive flag values encrypted at rest.
  • Threat model document.
The Steps

Build It

STEP 1

Add JWT authentication middleware

Install: npm install jsonwebtoken @types/jsonwebtoken

Create src/middleware/auth.ts:

import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

export interface AuthenticatedRequest extends Request {
  user?: { id: string; email: string; role: string };
}

export function authMiddleware(
  req: AuthenticatedRequest,
  res: Response,
  next: NextFunction
) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET || 'secret');
    req.user = decoded as any;
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
}

export function requireRole(role: string) {
  return (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
    if (req.user?.role !== role && req.user?.role !== 'admin') {
      return res.status(403).json({ error: 'Forbidden' });
    }
    next();
  };
}