Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

[Security] Enforce API Key Requirement in Production #69

@coderabbitai

Description

@coderabbitai

🔒 Priority: HIGH - Security & Stability

Background

The authentication middleware at backend/src/api/middleware/auth.js currently provides a default development API key that is too predictable and does not enforce API key configuration in production environments.

Current Implementation - Security Vulnerability

// backend/src/api/middleware/auth.js (lines 8-9)
const DEFAULT_API_KEY = process.env.API_KEY || 'dev-api-key-change-in-production';

export function authenticate(options = { required: true }) {
  return (req, res, next) => {
    // ... validation logic using DEFAULT_API_KEY
  };
}

Security Issues

  1. Predictable Default Key: 'dev-api-key-change-in-production' is too obvious
  2. No Production Enforcement: Server starts without API_KEY in production
  3. Single Shared Key: No support for multiple client keys or key rotation
  4. Key Exposure: API keys logged in session data (line 45-56)

Recommended Solution

Part 1: Enforce API_KEY in Production

// backend/src/api/middleware/auth.js
const DEFAULT_API_KEY = process.env.API_KEY;

// Startup validation
if (!DEFAULT_API_KEY && process.env.NODE_ENV === 'production') {
  console.error('❌ FATAL: API_KEY environment variable is required in production');
  throw new Error('API_KEY environment variable required in production');
}

if (DEFAULT_API_KEY && DEFAULT_API_KEY.length < 32) {
  console.warn('⚠️  WARNING: API_KEY should be at least 32 characters for security');
}

Part 2: Support Multiple API Keys with Scopes (Optional Enhancement)

// backend/src/api/middleware/auth.js
const API_KEYS = new Map([
  [process.env.API_KEY_ADMIN, { scope: 'admin', name: 'Admin Key' }],
  [process.env.API_KEY_TUI, { scope: 'tui', name: 'TUI Client' }],
  [process.env.API_KEY_BROWSER, { scope: 'browser', name: 'Browser Client' }],
  [process.env.API_KEY_READONLY, { scope: 'readonly', name: 'Read-Only Key' }]
].filter(([key]) => key)); // Remove undefined keys

export function authenticate(options = { required: true, scopes: [] }) {
  return (req, res, next) => {
    const apiKey = req.headers['x-api-key'];
    const keyInfo = API_KEYS.get(apiKey);
    
    if (!keyInfo) {
      return res.status(401).json({...});
    }
    
    // Scope validation
    if (options.scopes?.length && !options.scopes.includes(keyInfo.scope)) {
      return res.status(403).json({
        error: { message: 'Insufficient permissions' }
      });
    }
    
    req.clientId = keyInfo.name;
    req.scope = keyInfo.scope;
    next();
  };
}

Part 3: Hash API Keys Before Logging

// backend/src/api/middleware/auth.js
import crypto from 'crypto';

function hashApiKey(key) {
  return crypto.createHash('sha256').update(key).digest('hex').substring(0, 8);
}

// In session creation (line 45-56)
sessionData.apiKeyHash = hashApiKey(apiKey); // Don't store full key

Files to Modify

  • backend/src/api/middleware/auth.js (entire file refactor)
  • backend/src/server.js (add startup validation, lines 1-10)
  • .env.example (document required environment variables - NEW FILE)
  • README.md or deployment docs (update with security requirements)

Environment Variables

Create .env.example:

# Required in production
NODE_ENV=production
API_KEY=your-secure-random-key-minimum-32-characters-recommended-64

# Optional: Multiple API keys with scopes
API_KEY_ADMIN=admin-key-with-full-access
API_KEY_TUI=tui-client-key
API_KEY_BROWSER=browser-client-key
API_KEY_READONLY=readonly-key-for-monitoring

# Server configuration
PORT=3001
LOG_LEVEL=info

Acceptance Criteria

  • Server refuses to start in production without API_KEY environment variable
  • Startup validation checks API_KEY length (minimum 32 characters recommended)
  • Default development key removed or only available in development mode
  • API keys are hashed before logging or storing in sessions
  • .env.example file created with documentation
  • Deployment documentation updated with security requirements
  • (Optional) Multiple API key support with scopes implemented
  • (Optional) Endpoint added for key validation/testing

Startup Validation Test

# Should fail to start
NODE_ENV=production npm start

# Should warn about short key
NODE_ENV=production API_KEY=short npm start

# Should start successfully
NODE_ENV=production API_KEY=$(openssl rand -hex 32) npm start

Key Generation Command

# Generate secure API key
openssl rand -hex 32  # 64-character hex string
# or
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

References

Additional Context

This is a critical security issue that must be resolved before production deployment. Consider implementing key rotation strategy for long-running production systems.

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions