Comprehensive security hardening guide for production deployments
This guide provides detailed information about Bungate's security features, threat model, and best practices for securing your API gateway in production environments.
- Authentication Guide - JWT, API keys, OAuth2 configuration
- TLS Configuration Guide - Detailed HTTPS setup
- Quick Start - Basic security setup
- API Reference - Security configuration options
- Troubleshooting - Security-related issues
- Threat Model
- Security Features Overview
- TLS/HTTPS Configuration
- Input Validation & Sanitization
- Secure Error Handling
- Session Management
- Trusted Proxy Configuration
- Security Headers
- Request Size Limits
- JWT Key Rotation
- Common Security Scenarios
- Security Checklist
- Compliance & Standards
Bungate is designed to protect against the following attack vectors:
- Man-in-the-Middle (MITM) Attacks: Prevented through TLS/HTTPS encryption
- Eavesdropping: All traffic encrypted with strong cipher suites
- Protocol Downgrade Attacks: Minimum TLS version enforcement
- Injection Attacks: Path traversal, SQL injection, command injection
- Cross-Site Scripting (XSS): Security headers and CSP
- Cross-Site Request Forgery (CSRF): Token-based protection
- Information Disclosure: Secure error handling and sanitization
- Denial of Service (DoS): Request size limits and rate limiting
- Slowloris Attacks: Timeout management and connection limits
- Resource Amplification: Payload size monitoring
- Session Hijacking: Cryptographically secure session IDs
- Token Replay: JWT expiration and validation
- Credential Stuffing: Rate limiting and account lockout
- IP Spoofing: Trusted proxy validation
- Header Injection: Header validation and sanitization
- Configuration Tampering: Secure defaults and validation
Bungate provides defense-in-depth with multiple security layers. All security features are automatically applied when configured in the gateway's security configuration object. You don't need to manually add middleware to each route - the gateway handles this for you.
When you configure security features at the gateway level, they are automatically applied to all routes:
const gateway = new BunGateway({
security: {
// These features are automatically applied to ALL routes
tls: { enabled: true /* ... */ },
sizeLimits: { maxBodySize: 10 * 1024 * 1024 },
inputValidation: { blockedPatterns: [/\.\./] },
securityHeaders: { enabled: true },
},
})
// This route automatically gets all security features
gateway.addRoute({
pattern: '/api/*',
target: 'http://backend:3000',
})Security features are applied in the following order:
- Size Limits - Validates request sizes before processing
- Input Validation - Validates paths, headers, and query parameters
- Security Headers - Applied to all responses
- Authentication - JWT/API key validation (if configured)
- Rate Limiting - Request throttling (if configured)
- Route-specific middleware - Your custom middleware
Bungate provides defense-in-depth with multiple security layers:
┌─────────────────────────────────────────────────────────────┐
│ Client Requests │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 1: TLS Termination │
│ ✓ Certificate validation │
│ ✓ Cipher suite enforcement │
│ ✓ Protocol version validation │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 2: Request Validation │
│ ✓ Size limit enforcement │
│ ✓ Input validation & sanitization │
│ ✓ Header validation │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 3: Security Middleware │
│ ✓ Trusted proxy validation │
│ ✓ Security headers injection │
│ ✓ Authentication & authorization │
│ ✓ Rate limiting │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 4: Application Processing │
│ ✓ Routing & load balancing │
│ ✓ Circuit breaking │
│ ✓ Backend proxying │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 5: Response Processing │
│ ✓ Error sanitization │
│ ✓ Security header injection │
│ ✓ Payload size monitoring │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Backend Services │
└─────────────────────────────────────────────────────────────┘
TLS (Transport Layer Security) encrypts all traffic between clients and the gateway, preventing eavesdropping and man-in-the-middle attacks.
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 443 },
security: {
tls: {
enabled: true,
cert: './cert.pem',
key: './key.pem',
minVersion: 'TLSv1.3',
redirectHTTP: true,
redirectPort: 80,
},
},
})
await gateway.listen()const gateway = new BunGateway({
server: { port: 443 },
security: {
tls: {
enabled: true,
cert: process.env.TLS_CERT_PATH,
key: process.env.TLS_KEY_PATH,
ca: process.env.TLS_CA_PATH, // For client certificate validation
minVersion: 'TLSv1.3',
cipherSuites: [
'TLS_AES_256_GCM_SHA384',
'TLS_CHACHA20_POLY1305_SHA256',
'TLS_AES_128_GCM_SHA256',
],
requestCert: false, // Enable for mTLS
rejectUnauthorized: true,
redirectHTTP: true,
redirectPort: 80,
},
},
})- Use TLS 1.3: Provides better security and performance
- Strong Cipher Suites: Use AEAD ciphers with forward secrecy
- Valid Certificates: Obtain from trusted CAs (Let's Encrypt, DigiCert)
- Certificate Rotation: Automate renewal before expiration
- Secure Key Storage: Protect private keys with proper permissions (chmod 600)
- HTTP Redirect: Always redirect HTTP to HTTPS in production
For detailed TLS configuration, see TLS Configuration Guide.
Input validation prevents injection attacks by validating and sanitizing all user-provided data before processing.
Input validation is automatically applied when configured in the gateway security settings:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
security: {
inputValidation: {
maxPathLength: 2048,
maxHeaderSize: 16384,
maxHeaderCount: 100,
allowedPathChars: /^[a-zA-Z0-9\/_\-\.~%]+$/,
blockedPatterns: [
/\.\./, // Directory traversal
/%00/, // Null byte injection
/<script>/i, // XSS attempts
/javascript:/i, // JavaScript protocol
],
sanitizeHeaders: true,
},
},
})
// All routes automatically have input validation applied
gateway.addRoute({
pattern: '/api/*',
target: 'http://backend:3000',
})- Path Parameters: Checked against allowed character set
- Path Rewriting: Sanitized to prevent directory traversal
- Headers: Validated against RFC specifications
- Query Parameters: Checked for malicious patterns
- Request Size: Enforced before processing
import { InputValidator } from 'bungate'
const validator = new InputValidator({
maxPathLength: 1024,
allowedPathChars: /^[a-zA-Z0-9\/\-_]+$/,
})
gateway.addRoute({
pattern: '/strict/*',
target: 'http://backend:3000',
middlewares: [
async (req, next) => {
const result = validator.validatePath(new URL(req.url).pathname)
if (!result.valid) {
return new Response(
JSON.stringify({ error: 'Invalid path', details: result.errors }),
{ status: 400, headers: { 'Content-Type': 'application/json' } },
)
}
return next()
},
],
})- Directory Traversal:
../sequences blocked and sanitized - Null Byte Injection:
%00and null characters rejected - XSS Attempts: Script tags and JavaScript protocols blocked
- SQL Injection: Special characters in query params validated
- Command Injection: Shell metacharacters blocked
Secure error handling prevents information disclosure by sanitizing error messages in production while maintaining detailed logging for debugging.
Secure error handling is automatically applied when configured in the gateway security settings:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
security: {
errorHandling: {
production: process.env.NODE_ENV === 'production',
includeStackTrace: false,
logErrors: true,
sanitizeBackendErrors: true,
customMessages: {
500: 'An internal error occurred',
502: 'Service temporarily unavailable',
503: 'Service unavailable',
504: 'Request timeout',
},
},
},
})
// All routes automatically have secure error handling applied
gateway.addRoute({
pattern: '/api/*',
target: 'http://backend:3000',
})Production Mode (sanitized):
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"requestId": "req_abc123",
"timestamp": 1699564800000
}
}Development Mode (detailed):
{
"error": {
"code": "INTERNAL_ERROR",
"message": "Database connection failed: ECONNREFUSED",
"requestId": "req_abc123",
"timestamp": 1699564800000,
"stack": "Error: Database connection failed...",
"details": {
"host": "localhost",
"port": 5432
}
}
}import { SecureErrorHandler } from 'bungate'
const errorHandler = new SecureErrorHandler({
production: true,
logErrors: true,
})
gateway.addRoute({
pattern: '/api/*',
target: 'http://backend:3000',
hooks: {
onError: async (req, error) => {
// Log full error internally
errorHandler.logError(error, {
requestId: crypto.randomUUID(),
clientIP: req.headers.get('x-forwarded-for') || 'unknown',
path: new URL(req.url).pathname,
method: req.method,
})
// Return sanitized error to client
const safeError = errorHandler.sanitizeError(error)
return new Response(JSON.stringify(safeError), {
status: safeError.statusCode,
headers: { 'Content-Type': 'application/json' },
})
},
},
})- Stack traces (removed in production)
- Internal service URLs and IPs
- Database connection strings
- Environment variables
- File system paths
- Configuration details
- Backend error messages
Cryptographically secure session management prevents session hijacking and fixation attacks through strong random ID generation and secure cookie handling.
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
security: {
sessions: {
entropyBits: 128, // Minimum 128 bits
ttl: 3600000, // 1 hour
cookieName: 'session_id',
cookieOptions: {
secure: true, // HTTPS only
httpOnly: true, // No JavaScript access
sameSite: 'strict', // CSRF protection
domain: '.example.com',
path: '/',
},
},
},
})gateway.addRoute({
pattern: '/app/*',
loadBalancer: {
strategy: 'round-robin',
targets: [
{ url: 'http://app1:3000' },
{ url: 'http://app2:3000' },
{ url: 'http://app3:3000' },
],
stickySession: {
enabled: true,
cookieName: 'app_session',
ttl: 3600000,
},
},
})import { SessionManager } from 'bungate'
const sessionManager = new SessionManager({
entropyBits: 128,
ttl: 3600000,
})
// Generate secure session ID
const sessionId = sessionManager.generateSessionId()
console.log('Entropy:', sessionId.length * 4, 'bits') // 128+ bits
// Create session
const session = sessionManager.createSession('http://backend:3000/target')
// Validate session
const isValid = sessionManager.validateSessionId(sessionId)
// Get session
const session = sessionManager.getSession(sessionId)
// Delete session
sessionManager.deleteSession(sessionId)
// Cleanup expired sessions
sessionManager.cleanupExpiredSessions()- Cryptographic Randomness: Uses
crypto.randomBytes()for all session IDs - Minimum Entropy: Enforces 128 bits of entropy (32 hex characters)
- Automatic Expiration: Sessions expire after configured TTL
- Secure Cookies: Secure, HttpOnly, and SameSite attributes set by default
- Session Validation: Rejects sessions below minimum entropy threshold
- Use HTTPS (required for Secure cookie attribute)
- Set appropriate TTL based on application sensitivity
- Enable SameSite=strict for CSRF protection
- Implement session cleanup to prevent memory leaks
- Rotate session IDs after authentication
- Invalidate sessions on logout
Trusted proxy validation prevents IP spoofing by only accepting forwarded headers from verified proxy servers.
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
security: {
trustedProxies: {
enabled: true,
trustedIPs: [
'10.0.0.0/8', // Private network
'172.16.0.0/12', // Private network
'192.168.0.0/16', // Private network
],
trustedNetworks: [
'cloudflare', // Cloudflare IP ranges
'aws', // AWS CloudFront
'gcp', // Google Cloud CDN
'azure', // Azure CDN
],
maxForwardedDepth: 3,
trustAll: false, // Never use in production!
},
},
})Bungate includes IP ranges for major CDN and cloud providers:
- cloudflare: Cloudflare CDN IP ranges (complete list, updated Nov 2024)
- aws: AWS CloudFront IP ranges (representative sample of 194 ranges)
- gcp: Google Cloud CDN IP ranges (representative sample of 814 ranges)
- azure: Azure CDN IP ranges (representative sample)
Note: The built-in ranges are representative samples suitable for most deployments. For large-scale production environments or the most up-to-date ranges, consider fetching them dynamically:
// Example: Fetch AWS CloudFront ranges dynamically
const response = await fetch('https://ip-ranges.amazonaws.com/ip-ranges.json')
const data = await response.json()
const cloudfrontRanges = data.prefixes
.filter((p) => p.service === 'CLOUDFRONT')
.map((p) => p.ip_prefix)
// Use with custom validator
const validator = new TrustedProxyValidator({
trustedIPs: cloudfrontRanges,
})Update Sources:
- Cloudflare: https://www.cloudflare.com/ips-v4
- AWS CloudFront: https://ip-ranges.amazonaws.com/ip-ranges.json
- GCP: https://www.gstatic.com/ipranges/cloud.json
- Azure: https://www.microsoft.com/en-us/download/details.aspx?id=56519
import { TrustedProxyValidator } from 'bungate'
const validator = new TrustedProxyValidator({
trustedIPs: ['203.0.113.0/24'],
maxForwardedDepth: 2,
})
gateway.addRoute({
pattern: '/api/*',
target: 'http://backend:3000',
middlewares: [
async (req, next) => {
const remoteIP = req.headers.get('x-real-ip') || 'unknown'
if (!validator.validateProxy(remoteIP)) {
console.warn('Untrusted proxy detected:', remoteIP)
// Use direct connection IP instead
}
const clientIP = validator.extractClientIP(req)
;(req as any).clientIP = clientIP
return next()
},
],
})- Proxy Validation: Checks if request comes from trusted proxy
- Header Extraction: Only processes X-Forwarded-For from trusted sources
- Chain Validation: Validates entire forwarded header chain
- Depth Limiting: Prevents header chain manipulation
- Fallback: Uses direct connection IP if proxy untrusted
trustedIPs: [
'10.0.0.1', // Single IP
'192.168.1.0/24', // Subnet (256 IPs)
'172.16.0.0/12', // Large subnet
'2001:db8::/32', // IPv6 subnet
]The system logs warnings for suspicious activity:
// Logged when:
// - Forwarded header from untrusted source
// - Chain depth exceeds maximum
// - Invalid IP format detected
// - Conflicting forwarded headers- Never use
trustAll: truein production - Regularly update trusted IP ranges
- Monitor security logs for suspicious activity
- Use specific IP ranges instead of broad subnets
- Validate forwarded headers even from trusted proxies
- Set appropriate
maxForwardedDepth(typically 1-3)
Security headers instruct browsers to enforce additional security protections, preventing various client-side attacks.
Security headers are automatically applied to all responses when configured in the gateway security settings:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
security: {
securityHeaders: {
enabled: true,
hsts: {
maxAge: 31536000, // 1 year
includeSubDomains: true,
preload: true,
},
contentSecurityPolicy: {
directives: {
'default-src': ["'self'"],
'script-src': ["'self'", "'unsafe-inline'", 'cdn.example.com'],
'style-src': ["'self'", "'unsafe-inline'"],
'img-src': ["'self'", 'data:', 'https:'],
'font-src': ["'self'", 'fonts.gstatic.com'],
'connect-src': ["'self'", 'api.example.com'],
'frame-ancestors': ["'none'"],
'base-uri': ["'self'"],
'form-action': ["'self'"],
},
reportOnly: false,
},
xFrameOptions: 'DENY',
xContentTypeOptions: true,
referrerPolicy: 'strict-origin-when-cross-origin',
permissionsPolicy: {
camera: [],
microphone: [],
geolocation: ["'self'"],
payment: ["'self'"],
},
customHeaders: {
'X-Gateway-Version': '1.0.0',
},
},
},
})
// All routes automatically have security headers applied to responses
gateway.addRoute({
pattern: '/api/*',
target: 'http://backend:3000',
})Forces browsers to use HTTPS for all future requests.
hsts: {
maxAge: 31536000, // Required: seconds to remember
includeSubDomains: true, // Apply to all subdomains
preload: true, // Submit to HSTS preload list
}Response Header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Controls which resources browsers can load, preventing XSS attacks.
contentSecurityPolicy: {
directives: {
'default-src': ["'self'"], // Default policy
'script-src': ["'self'", 'trusted-cdn.com'], // JavaScript sources
'style-src': ["'self'", "'unsafe-inline'"], // CSS sources
'img-src': ["'self'", 'data:', 'https:'], // Image sources
'connect-src': ["'self'", 'api.example.com'], // AJAX/WebSocket
'font-src': ["'self'", 'fonts.gstatic.com'], // Font sources
'object-src': ["'none'"], // Plugins (Flash, etc.)
'frame-ancestors': ["'none'"], // Embedding restrictions
'base-uri': ["'self'"], // <base> tag restrictions
'form-action': ["'self'"], // Form submission targets
},
reportOnly: false, // Set true for testing
}Response Header:
Content-Security-Policy: default-src 'self'; script-src 'self' trusted-cdn.com; ...
Prevents clickjacking by controlling iframe embedding.
xFrameOptions: 'DENY' | 'SAMEORIGIN' | 'ALLOW-FROM https://example.com'Response Header:
X-Frame-Options: DENY
Prevents MIME type sniffing.
xContentTypeOptions: trueResponse Header:
X-Content-Type-Options: nosniff
Controls referrer information sent with requests.
referrerPolicy: 'no-referrer' |
'no-referrer-when-downgrade' |
'origin' |
'origin-when-cross-origin' |
'same-origin' |
'strict-origin' |
'strict-origin-when-cross-origin' |
'unsafe-url'Response Header:
Referrer-Policy: strict-origin-when-cross-origin
Controls browser features and APIs.
permissionsPolicy: {
camera: [], // Disable camera
microphone: [], // Disable microphone
geolocation: ["'self'"], // Allow on same origin
payment: ["'self'"], // Allow payment API
usb: [], // Disable USB access
'display-capture': [], // Disable screen capture
}Response Header:
Permissions-Policy: camera=(), microphone=(), geolocation=(self), payment=(self)
Test CSP without blocking resources:
contentSecurityPolicy: {
directives: { /* ... */ },
reportOnly: true,
reportUri: '/csp-report',
}Violations are reported but not blocked, allowing you to test policies safely.
Add application-specific security headers:
customHeaders: {
'X-Gateway-Version': '1.0.0',
'X-Request-ID': () => crypto.randomUUID(),
'X-Content-Type-Options': 'nosniff',
}- Start with Report-Only: Test CSP before enforcing
- Minimize 'unsafe-inline': Avoid inline scripts/styles
- Use Nonces: For inline scripts that can't be avoided
- Enable HSTS: After confirming HTTPS works correctly
- Submit to Preload: After testing HSTS for several weeks
- Regular Updates: Review and update CSP as application evolves
- Monitor Reports: Set up CSP reporting endpoint
Request size limits prevent denial-of-service attacks by rejecting oversized requests before they consume resources.
Request size limits are automatically enforced when configured in the gateway security settings:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
security: {
sizeLimits: {
maxBodySize: 10 * 1024 * 1024, // 10 MB
maxHeaderSize: 16 * 1024, // 16 KB
maxHeaderCount: 100, // 100 headers
maxUrlLength: 2048, // 2048 characters
maxQueryParams: 100, // 100 parameters
},
},
})
// All routes automatically have size limits enforced
gateway.addRoute({
pattern: '/*',
target: 'http://backend:3000',
})Size limits are configured globally at the gateway level and apply to all routes:
const gateway = new BunGateway({
server: { port: 3000 },
security: {
sizeLimits: {
maxBodySize: 10 * 1024 * 1024, // 10 MB default
maxHeaderSize: 16 * 1024, // 16 KB
maxHeaderCount: 100,
maxUrlLength: 2048,
maxQueryParams: 100,
},
},
})
// For different limits per route, you can use custom middleware
import { createSizeLimiterMiddleware } from 'bungate'
gateway.addRoute({
pattern: '/upload/*',
target: 'http://upload-service:3000',
middlewares: [
createSizeLimiterMiddleware({
limits: {
maxBodySize: 100 * 1024 * 1024, // 100 MB for uploads
},
}),
],
})import { SizeLimiter } from 'bungate'
const limiter = new SizeLimiter({
maxBodySize: 5 * 1024 * 1024,
maxHeaderSize: 16 * 1024,
})
gateway.addRoute({
pattern: '/custom/*',
target: 'http://backend:3000',
middlewares: [
async (req, next) => {
// Validate request size
const result = limiter.validateRequestSize(req)
if (!result.valid) {
return new Response(
JSON.stringify({
error: 'Request too large',
details: result.errors,
}),
{
status: 413,
headers: { 'Content-Type': 'application/json' },
},
)
}
return next()
},
],
})Different limits return appropriate status codes:
- 413 Payload Too Large: Body size exceeds limit
- 414 URI Too Long: URL length exceeds limit
- 431 Request Header Fields Too Large: Headers exceed limits
Bungate uses secure defaults based on RFC recommendations:
{
maxBodySize: 10 * 1024 * 1024, // 10 MB
maxHeaderSize: 16 * 1024, // 16 KB (per header)
maxHeaderCount: 100, // 100 headers
maxUrlLength: 2048, // 2048 characters
maxQueryParams: 100, // 100 parameters
}Body size is validated during streaming to prevent buffering large payloads:
// Size is checked incrementally as data arrives
// Request is aborted immediately when limit exceeded
// No memory exhaustion from buffering- Set Appropriate Limits: Based on application requirements
- Different Limits per Route: Upload endpoints need larger limits
- Monitor Rejections: Track 413/414/431 responses
- Document Limits: Inform API consumers of size restrictions
- Graceful Errors: Return helpful error messages
- Consider Compression: Compressed payloads count toward limits
- DoS Prevention: Rejects oversized requests early
- Memory Protection: Prevents memory exhaustion
- Resource Conservation: Saves CPU and bandwidth
- Attack Surface Reduction: Limits potential attack vectors
JWT key rotation allows updating signing keys without service disruption, enabling recovery from key compromise and regular key rotation best practices.
JWT key rotation is configured at the gateway level and can be used with route-level authentication:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
security: {
jwtKeyRotation: {
secrets: [
{
key: process.env.JWT_SECRET_PRIMARY,
algorithm: 'HS256',
kid: 'key-2024-01',
primary: true,
},
{
key: process.env.JWT_SECRET_OLD,
algorithm: 'HS256',
kid: 'key-2023-12',
deprecated: true,
},
],
gracePeriod: 7 * 24 * 60 * 60 * 1000, // 7 days
},
},
})
// Use with route authentication
gateway.addRoute({
pattern: '/api/*',
target: 'http://backend:3000',
auth: {
secret: process.env.JWT_SECRET_PRIMARY,
jwtOptions: {
algorithms: ['HS256'],
},
},
})Automatically fetch and refresh keys from JWKS endpoint:
security: {
jwtKeyRotation: {
jwksUri: 'https://auth.example.com/.well-known/jwks.json',
jwksRefreshInterval: 3600000, // 1 hour
secrets: [
{
key: process.env.JWT_FALLBACK_SECRET,
algorithm: 'HS256',
kid: 'fallback',
},
],
},
}- Add New Key: Add new key as primary
- Grace Period: Keep old key for verification
- Monitor Usage: Track deprecated key usage
- Remove Old Key: After grace period expires
// Step 1: Add new key (both keys active)
secrets: [
{ key: 'new-secret', algorithm: 'HS256', kid: 'key-2024-02', primary: true },
{
key: 'old-secret',
algorithm: 'HS256',
kid: 'key-2024-01',
deprecated: true,
},
]
// Step 2: Monitor for 7 days
// Logs warnings when old key is used
// Step 3: Remove old key (after grace period)
secrets: [
{ key: 'new-secret', algorithm: 'HS256', kid: 'key-2024-02', primary: true },
]Support different algorithms simultaneously:
secrets: [
{
key: rsaPublicKey,
algorithm: 'RS256',
kid: 'rsa-key-1',
primary: true,
},
{
key: 'hmac-secret',
algorithm: 'HS256',
kid: 'hmac-key-1',
},
{
key: ecPublicKey,
algorithm: 'ES256',
kid: 'ec-key-1',
},
]import { JWTKeyRotationManager } from 'bungate'
const keyManager = new JWTKeyRotationManager({
secrets: [
{ key: 'primary-secret', algorithm: 'HS256', primary: true },
{ key: 'old-secret', algorithm: 'HS256', deprecated: true },
],
gracePeriod: 7 * 24 * 60 * 60 * 1000,
})
// Verify token (tries all keys)
try {
const payload = await keyManager.verifyToken(token)
console.log('Token valid:', payload)
} catch (error) {
console.error('Token invalid:', error)
}
// Sign new token (uses primary key)
const newToken = await keyManager.signToken({
sub: 'user123',
exp: Math.floor(Date.now() / 1000) + 3600,
})
// Rotate keys
await keyManager.rotateKeys()
// Refresh JWKS
await keyManager.refreshJWKS()The system logs warnings for security monitoring:
// Logged when:
// - Deprecated key used for verification
// - JWKS refresh fails
// - All keys fail verification
// - Key rotation performed- Regular Rotation: Rotate keys every 90 days
- Grace Period: Keep old keys for 7-14 days
- Monitor Usage: Track deprecated key usage
- Secure Storage: Store keys in secrets management system
- Key IDs: Use descriptive key IDs with dates
- JWKS Caching: Cache JWKS responses appropriately
- Fallback Keys: Keep fallback key for emergencies
- Audit Logs: Log all key rotation events
In case of key compromise:
// 1. Immediately add new key as primary
secrets: [
{
key: 'emergency-new-key',
algorithm: 'HS256',
kid: 'emergency-2024',
primary: true,
},
// Remove compromised key immediately (no grace period)
]
// 2. Invalidate all existing tokens
// 3. Force re-authentication
// 4. Investigate compromise
// 5. Update monitoring and alerts- Key Compromise Recovery: Replace compromised keys without downtime
- Regular Rotation: Follow security best practices
- Zero Downtime: Seamless key updates
- Backward Compatibility: Support old tokens during transition
- Monitoring: Track key usage and deprecation
Complete security configuration for production API gateway:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 443 },
// TLS/HTTPS
security: {
tls: {
enabled: true,
cert: process.env.TLS_CERT_PATH,
key: process.env.TLS_KEY_PATH,
minVersion: 'TLSv1.3',
redirectHTTP: true,
redirectPort: 80,
},
// Input validation
inputValidation: {
maxPathLength: 2048,
maxHeaderSize: 16384,
maxHeaderCount: 100,
sanitizeHeaders: true,
},
// Error handling
errorHandling: {
production: true,
includeStackTrace: false,
logErrors: true,
sanitizeBackendErrors: true,
},
// Session management
sessions: {
entropyBits: 128,
ttl: 3600000,
cookieOptions: {
secure: true,
httpOnly: true,
sameSite: 'strict',
},
},
// Trusted proxies
trustedProxies: {
enabled: true,
trustedNetworks: ['cloudflare'],
maxForwardedDepth: 2,
},
// Security headers
securityHeaders: {
enabled: true,
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
contentSecurityPolicy: {
directives: {
'default-src': ["'self'"],
'script-src': ["'self'"],
'style-src': ["'self'"],
'img-src': ["'self'", 'https:'],
'frame-ancestors': ["'none'"],
},
},
xFrameOptions: 'DENY',
xContentTypeOptions: true,
},
// Size limits
sizeLimits: {
maxBodySize: 10 * 1024 * 1024,
maxHeaderSize: 16 * 1024,
maxHeaderCount: 100,
maxUrlLength: 2048,
},
// JWT key rotation
jwtKeyRotation: {
secrets: [
{
key: process.env.JWT_SECRET_PRIMARY,
algorithm: 'HS256',
kid: 'primary',
primary: true,
},
],
jwksUri: process.env.JWKS_URI,
jwksRefreshInterval: 3600000,
},
},
})
// Protected API routes
gateway.addRoute({
pattern: '/api/*',
target: 'http://api-backend:3000',
auth: {
secret: process.env.JWT_SECRET_PRIMARY,
jwtOptions: {
algorithms: ['HS256'],
issuer: 'https://auth.example.com',
audience: 'https://api.example.com',
},
},
rateLimit: {
max: 1000,
windowMs: 60000,
},
circuitBreaker: {
enabled: true,
failureThreshold: 5,
timeout: 5000,
},
})
await gateway.listen()Gateway for microservices with different security requirements:
const gateway = new BunGateway({
server: { port: 443 },
security: {
/* ... base security config ... */
},
})
// Public API with API key auth
gateway.addRoute({
pattern: '/public/api/*',
target: 'http://public-service:3000',
auth: {
apiKeys: async (key) => await validateApiKey(key),
apiKeyHeader: 'x-api-key',
},
rateLimit: {
max: 100,
windowMs: 60000,
},
})
// Internal API with JWT auth
gateway.addRoute({
pattern: '/internal/api/*',
target: 'http://internal-service:3000',
auth: {
secret: process.env.INTERNAL_JWT_SECRET,
jwtOptions: {
algorithms: ['HS256'],
issuer: 'https://internal.example.com',
},
},
rateLimit: {
max: 10000,
windowMs: 60000,
},
})
// Admin API with strict security
gateway.addRoute({
pattern: '/admin/api/*',
target: 'http://admin-service:3000',
auth: {
secret: process.env.ADMIN_JWT_SECRET,
jwtOptions: {
algorithms: ['RS256'],
issuer: 'https://admin.example.com',
},
},
rateLimit: {
max: 50,
windowMs: 60000,
},
middlewares: [
// Additional admin validation
async (req, next) => {
const user = (req as any).user
if (!user?.roles?.includes('admin')) {
return new Response('Forbidden', { status: 403 })
}
return next()
},
],
})Maximum security for sensitive financial data:
const gateway = new BunGateway({
server: { port: 443 },
security: {
// Strict TLS
tls: {
enabled: true,
cert: process.env.TLS_CERT_PATH,
key: process.env.TLS_KEY_PATH,
minVersion: 'TLSv1.3',
cipherSuites: ['TLS_AES_256_GCM_SHA384', 'TLS_CHACHA20_POLY1305_SHA256'],
requestCert: true, // mTLS required
rejectUnauthorized: true,
},
// Strict input validation
inputValidation: {
maxPathLength: 1024,
maxHeaderSize: 8192,
maxHeaderCount: 50,
allowedPathChars: /^[a-zA-Z0-9\/_-]+$/,
sanitizeHeaders: true,
},
// Strict size limits
sizeLimits: {
maxBodySize: 1 * 1024 * 1024, // 1 MB
maxHeaderSize: 8 * 1024,
maxHeaderCount: 50,
maxUrlLength: 1024,
},
// Short session TTL
sessions: {
entropyBits: 256, // Extra entropy
ttl: 900000, // 15 minutes
cookieOptions: {
secure: true,
httpOnly: true,
sameSite: 'strict',
},
},
// Comprehensive security headers
securityHeaders: {
enabled: true,
hsts: {
maxAge: 63072000, // 2 years
includeSubDomains: true,
preload: true,
},
contentSecurityPolicy: {
directives: {
'default-src': ["'none'"],
'script-src': ["'self'"],
'style-src': ["'self'"],
'img-src': ["'self'"],
'connect-src': ["'self'"],
'frame-ancestors': ["'none'"],
'base-uri': ["'none'"],
'form-action': ["'self'"],
},
},
xFrameOptions: 'DENY',
xContentTypeOptions: true,
referrerPolicy: 'no-referrer',
},
},
})
// Payment endpoints with maximum security
gateway.addRoute({
pattern: '/payments/*',
target: 'http://payment-service:3000',
auth: {
secret: process.env.PAYMENT_JWT_SECRET,
jwtOptions: {
algorithms: ['RS256'],
issuer: 'https://auth.financial.example.com',
audience: 'https://api.financial.example.com',
},
},
rateLimit: {
max: 10, // Very strict rate limit
windowMs: 60000,
},
circuitBreaker: {
enabled: true,
failureThreshold: 3,
timeout: 3000,
},
middlewares: [
// Additional payment validation
async (req, next) => {
// Validate payment-specific requirements
// Check transaction limits
// Verify account status
return next()
},
],
})Relaxed security for development with detailed errors:
const gateway = new BunGateway({
server: { port: 3000 },
security: {
// No TLS in development
tls: {
enabled: false,
},
// Detailed errors
errorHandling: {
production: false,
includeStackTrace: true,
logErrors: true,
},
// Relaxed limits
sizeLimits: {
maxBodySize: 50 * 1024 * 1024, // 50 MB
maxHeaderSize: 32 * 1024,
maxHeaderCount: 200,
},
// Trust all proxies (local development)
trustedProxies: {
enabled: true,
trustAll: true, // OK for development only
},
},
})
// Development routes with optional auth
gateway.addRoute({
pattern: '/api/*',
target: 'http://localhost:3001',
auth: {
secret: 'dev-secret',
optional: true, // Allow unauthenticated requests
},
})Use this checklist to ensure your Bungate deployment is properly secured:
- TLS enabled with valid certificates from trusted CA
- Minimum TLS version set to 1.3 (or 1.2 minimum)
- Strong cipher suites configured
- HTTP to HTTPS redirect enabled
- HSTS header enabled with appropriate max-age
- Certificates monitored for expiration
- Private keys secured with proper permissions (chmod 600)
- Certificate rotation process documented
- Input validation enabled for all routes
- Path validation with allowed character set
- Header validation against RFC specifications
- Query parameter validation enabled
- Malicious pattern detection configured
- Path sanitization for rewrites
- Custom validation for sensitive endpoints
- Production mode enabled in production
- Stack traces disabled in production
- Error logging enabled
- Backend errors sanitized
- Custom error messages configured
- Request IDs included in errors
- Error monitoring and alerting set up
- Minimum 128 bits of entropy for session IDs
- Appropriate session TTL configured
- Secure cookie attribute enabled (HTTPS only)
- HttpOnly cookie attribute enabled
- SameSite cookie attribute set to 'strict' or 'lax'
- Session cleanup scheduled
- Session rotation after authentication
- Trusted proxy validation enabled
- Specific trusted IP ranges configured (not trustAll)
- Trusted networks configured for CDN/cloud providers
- Maximum forwarded depth set appropriately
- Security warnings monitored
- IP spoofing prevention verified
- Security headers enabled
- HSTS configured with appropriate max-age
- Content Security Policy configured
- X-Frame-Options set to DENY or SAMEORIGIN
- X-Content-Type-Options enabled
- Referrer-Policy configured
- Permissions-Policy configured
- CSP tested in report-only mode first
- Body size limits configured
- Header size limits configured
- URL length limits configured
- Query parameter count limits configured
- Per-route limits configured where needed
- Appropriate HTTP status codes returned
- Size limit rejections monitored
- JWT authentication configured
- Strong JWT secrets used
- JWT expiration configured
- JWT key rotation implemented
- JWKS refresh configured (if applicable)
- API key authentication for public APIs
- Rate limiting per user/API key
- Authentication excluded for public endpoints only
- Rate limiting enabled for all routes
- Appropriate limits per route type
- Custom key generation for user-based limiting
- Distributed rate limiting for clusters
- Rate limit exceeded responses monitored
- Whitelist for trusted clients (if needed)
- Structured logging enabled
- Security events logged
- Failed authentication attempts logged
- Rate limit violations logged
- Input validation failures logged
- Error logs monitored
- Security alerts configured
- Metrics collection enabled
- Gateway running in cluster mode for production
- Health checks configured
- Circuit breakers enabled for backend services
- Graceful shutdown configured
- Connection draining implemented
- Environment variables secured
- Secrets management system used
- Regular security updates applied
- Security requirements documented
- Threat model reviewed
- Security testing performed
- Penetration testing completed
- Compliance requirements met (PCI DSS, HIPAA, etc.)
- Security audit trail maintained
- Incident response plan documented
- Regular security reviews scheduled
Bungate addresses the OWASP Top 10 security risks:
- Mitigation: JWT authentication, API key validation, role-based access control
- Features: Auth middleware, token validation, custom authorization logic
- Mitigation: TLS 1.3, strong cipher suites, secure session IDs
- Features: TLS configuration, cryptographic random generation, HSTS
- Mitigation: Input validation, path sanitization, header validation
- Features: Input validator, malicious pattern detection, query param validation
- Mitigation: Secure defaults, defense-in-depth, threat modeling
- Features: Security configuration, multiple security layers, secure error handling
- Mitigation: Secure defaults, configuration validation, security headers
- Features: Default security settings, config validation, comprehensive headers
- Mitigation: Regular updates, dependency scanning, minimal dependencies
- Features: Automated security scanning, update notifications
- Mitigation: Strong session management, JWT validation, key rotation
- Features: Cryptographic session IDs, JWT key rotation, multi-factor support
- Mitigation: JWT signature validation, secure key management
- Features: JWT verification, key rotation, JWKS support
- Mitigation: Comprehensive logging, security event tracking, metrics
- Features: Structured logging, security alerts, monitoring integration
- Mitigation: Input validation, URL sanitization, trusted proxy validation
- Features: Path validation, header validation, proxy IP verification
Bungate supports PCI DSS requirements:
- Requirement 2: Strong cryptography (TLS 1.3, strong ciphers)
- Requirement 4: Encrypted transmission (TLS/HTTPS)
- Requirement 6: Secure development (input validation, secure defaults)
- Requirement 8: Strong authentication (JWT, API keys, session management)
- Requirement 10: Logging and monitoring (comprehensive audit logs)
Security features for HIPAA compliance:
- Access Control: JWT authentication, role-based access
- Audit Controls: Comprehensive logging and monitoring
- Integrity: JWT signature validation, secure error handling
- Transmission Security: TLS 1.3 encryption, strong cipher suites
Privacy and security features:
- Data Protection: TLS encryption, secure session management
- Access Control: Authentication and authorization
- Audit Trail: Comprehensive logging
- Data Minimization: Secure error handling (no PII in errors)
Security controls for SOC 2 compliance:
- Security: TLS, authentication, input validation, rate limiting
- Availability: Circuit breakers, health checks, load balancing
- Confidentiality: Encryption, access control, secure sessions
- Processing Integrity: Input validation, error handling
- Privacy: Secure error handling, data protection
-
Static Application Security Testing (SAST)
- Code analysis for security vulnerabilities
- Configuration validation
- Dependency scanning
-
Dynamic Application Security Testing (DAST)
- Runtime security testing
- Penetration testing
- Vulnerability scanning
-
Security Unit Tests
- Input validation tests
- Authentication tests
- Authorization tests
- Error handling tests
-
Integration Security Tests
- End-to-end security flows
- TLS configuration tests
- Rate limiting tests
- Circuit breaker tests
-
Penetration Testing
- Professional security assessment
- Attack simulation
- Vulnerability exploitation
- Security posture validation
- OWASP ZAP - Security testing
- Burp Suite - Penetration testing
- SSL Labs - TLS configuration testing
- Security Headers - Header validation
If you discover a security vulnerability in Bungate:
- Do Not open a public GitHub issue
- Email security concerns to: security@21no.de
- Include detailed information:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
- Allow reasonable time for response and fix
- Coordinate disclosure timing
- Security updates are released as soon as possible
- Critical vulnerabilities are patched within 24-48 hours
- Security advisories published on GitHub
- Subscribe to releases for notifications
Bungate provides comprehensive security features for production API gateways:
- Transport Security: TLS 1.3 with strong cipher suites
- Input Protection: Validation and sanitization
- Error Security: Sanitized error responses
- Session Security: Cryptographic session management
- Network Security: Trusted proxy validation
- Client Security: Security headers and CSP
- Resource Protection: Size limits and rate limiting
- Authentication: JWT with key rotation support
Follow the security checklist and best practices to ensure your deployment is properly secured. Regular security reviews and updates are essential for maintaining a strong security posture.
For questions or security concerns, contact security@21no.de.