Script Valley
REST API Development: Complete Course from Beginner to Production
Authentication and Security in REST APIsLesson 4.2

API Key Authentication and Role-Based Access Control

API keys, API key generation, API key middleware, RBAC, role-based access control, permissions, admin middleware, resource ownership

API Key Authentication and Role-Based Access Control

JWT is ideal for user-facing authentication, but machine-to-machine API communication often uses API keys — long random tokens that identify and authenticate a service or client application. Role-Based Access Control (RBAC) then determines what authenticated users or services are allowed to do.

API Key Design

A good API key is a cryptographically random string of sufficient length (at least 32 bytes). Prefix it with a service identifier for easier identification: sk_live_a1b2c3d4e5f6.... Never send API keys as URL query parameters (they end up in server logs). Send them in the Authorization header or a custom X-API-Key header.

const crypto = require('crypto');

const generateApiKey = () => {
  return 'sk_live_' + crypto.randomBytes(32).toString('hex');
};

API Key Middleware

const apiKeyAuth = async (req, res, next) => {
  const key = req.headers['x-api-key'];
  if (!key) return res.status(401).json({ error: { code: 'API_KEY_MISSING' } });

  const hashedKey = crypto.createHash('sha256').update(key).digest('hex');
  const client = await ApiClient.findOne({ keyHash: hashedKey, isActive: true });

  if (!client) return res.status(401).json({ error: { code: 'API_KEY_INVALID' } });
  req.client = client;
  next();
};

Store only the hash of the API key in the database — never the plaintext. This way, a database breach does not expose active keys.

Role-Based Access Control

const authorize = (...roles) => (req, res, next) => {
  if (!roles.includes(req.user.role)) {
    return res.status(403).json({
      success: false,
      error: { code: 'FORBIDDEN', message: 'Insufficient permissions' }
    });
  }
  next();
};

router.delete('/:id', protect, authorize('admin'), deleteUser);

Up next

REST API Security: CORS, Helmet, Rate Limiting, and Input Sanitization

Sign in to track progress