Section 08

API & Microservices Architecture

Microservices architectures introduce new security challenges: more network communication, more attack surface, and complex trust relationships. Securing APIs becomes critical.

API Gateway Security

The API Gateway is your first line of defense. It centralizes security controls before requests reach backend services.

Authentication

  • • OAuth 2.0 / OpenID Connect
  • • API key validation
  • • JWT verification
  • • mTLS for B2B APIs

Traffic Management

  • • Rate limiting per client
  • • Request throttling
  • • Quota enforcement
  • • DDoS protection

Request Validation

  • • Schema validation (OpenAPI)
  • • Input sanitization
  • • Request size limits
  • • Content-Type enforcement

Observability

  • • Request/response logging
  • • Metrics and tracing
  • • Anomaly detection
  • • Audit trails

Service-to-Service Authentication

Mutual TLS (mTLS)

Both client and server present certificates. Provides authentication and encryption.

  • • Typically managed by service mesh
  • • Automatic certificate rotation
  • • No application code changes needed

Service Account Tokens

Short-lived tokens issued to services (Kubernetes service accounts, AWS IAM roles).

  • • Workload identity in cloud environments
  • • No static credentials to manage
  • • Automatic token refresh

JWT Service Tokens

Services authenticate with signed JWTs containing claims about identity and permissions.

  • • Signed by trusted issuer
  • • Contains scope/permissions claims
  • • Verify signature and claims at each service

OWASP API Security Top 10 (2023)

ID Risk Mitigation
API1 Broken Object Level Authorization Check ownership at resource level, not just endpoint
API2 Broken Authentication OAuth 2.0 + PKCE, rotate tokens, rate-limit auth endpoints
API3 Broken Object Property Level Authorization Return only allowed fields per role, never mass-assign
API4 Unrestricted Resource Consumption Rate limit, pagination, max payload size, timeout
API5 Broken Function Level Authorization Consistent authz middleware, deny by default
API6 Unrestricted Access to Sensitive Flows CAPTCHA, device fingerprinting, anti-automation
API7 Server Side Request Forgery URL allowlists, block internal ranges, validate schemes
API8 Security Misconfiguration Hardened defaults, automated config scanning
API9 Improper Inventory Management API catalog, deprecation policy, version sunset dates
API10 Unsafe Consumption of APIs Validate 3rd-party responses, timeout, circuit break

Practical: Redis Sliding Window Rate Limiter

rate-limiter.py
python
"""Sliding window rate limiter using Redis sorted sets."""
import time
import redis

r = redis.Redis(host="localhost", port=6379, decode_responses=True)

def is_rate_limited(client_id: str, max_requests: int = 100, window_sec: int = 60) -> bool:
    """Returns True if the client has exceeded their rate limit."""
    key = f"ratelimit:{client_id}"
    now = time.time()
    window_start = now - window_sec

    pipe = r.pipeline()
    # Remove expired entries
    pipe.zremrangebyscore(key, 0, window_start)
    # Add current request
    pipe.zadd(key, {f"{now}": now})
    # Count requests in window
    pipe.zcard(key)
    # Set TTL so keys auto-expire
    pipe.expire(key, window_sec)
    results = pipe.execute()

    request_count = results[2]
    return request_count > max_requests

# Usage in Flask middleware:
@app.before_request
def check_rate_limit():
    client_id = request.headers.get("X-API-Key", request.remote_addr)
    if is_rate_limited(client_id, max_requests=100, window_sec=60):
        return jsonify({"error": "rate_limit_exceeded"}), 429
"""Sliding window rate limiter using Redis sorted sets."""
import time
import redis

r = redis.Redis(host="localhost", port=6379, decode_responses=True)

def is_rate_limited(client_id: str, max_requests: int = 100, window_sec: int = 60) -> bool:
    """Returns True if the client has exceeded their rate limit."""
    key = f"ratelimit:{client_id}"
    now = time.time()
    window_start = now - window_sec

    pipe = r.pipeline()
    # Remove expired entries
    pipe.zremrangebyscore(key, 0, window_start)
    # Add current request
    pipe.zadd(key, {f"{now}": now})
    # Count requests in window
    pipe.zcard(key)
    # Set TTL so keys auto-expire
    pipe.expire(key, window_sec)
    results = pipe.execute()

    request_count = results[2]
    return request_count > max_requests

# Usage in Flask middleware:
@app.before_request
def check_rate_limit():
    client_id = request.headers.get("X-API-Key", request.remote_addr)
    if is_rate_limited(client_id, max_requests=100, window_sec=60):
        return jsonify({"error": "rate_limit_exceeded"}), 429

Practical: Kong API Gateway Security Config

kong-security.yaml
yaml
# Kong declarative config — security plugins
_format_version: "3.0"

services:
  - name: backend-api
    url: http://api-server:8080
    routes:
      - name: api-route
        paths: ["/api/v1"]
        strip_path: false

plugins:
  # JWT authentication
  - name: jwt
    config:
      claims_to_verify: ["exp"]
      key_claim_name: "kid"
      secret_is_base64: false

  # Rate limiting (sliding window)
  - name: rate-limiting-advanced
    config:
      limit: [100]
      window_size: [60]
      identifier: consumer
      sync_rate: 10
      strategy: sliding
      namespace: api-v1

  # Request size limiting (prevent DoS)
  - name: request-size-limiting
    config:
      allowed_payload_size: 1  # 1 MB max

  # CORS
  - name: cors
    config:
      origins: ["https://app.example.com"]
      methods: ["GET", "POST", "PUT", "DELETE"]
      headers: ["Authorization", "Content-Type"]
      max_age: 3600

  # IP restriction for admin endpoints
  - name: ip-restriction
    route: admin-route
    config:
      allow: ["10.0.0.0/8"]
      deny: []
# Kong declarative config — security plugins
_format_version: "3.0"

services:
  - name: backend-api
    url: http://api-server:8080
    routes:
      - name: api-route
        paths: ["/api/v1"]
        strip_path: false

plugins:
  # JWT authentication
  - name: jwt
    config:
      claims_to_verify: ["exp"]
      key_claim_name: "kid"
      secret_is_base64: false

  # Rate limiting (sliding window)
  - name: rate-limiting-advanced
    config:
      limit: [100]
      window_size: [60]
      identifier: consumer
      sync_rate: 10
      strategy: sliding
      namespace: api-v1

  # Request size limiting (prevent DoS)
  - name: request-size-limiting
    config:
      allowed_payload_size: 1  # 1 MB max

  # CORS
  - name: cors
    config:
      origins: ["https://app.example.com"]
      methods: ["GET", "POST", "PUT", "DELETE"]
      headers: ["Authorization", "Content-Type"]
      max_age: 3600

  # IP restriction for admin endpoints
  - name: ip-restriction
    route: admin-route
    config:
      allow: ["10.0.0.0/8"]
      deny: []

API Security Tools

Category Tool Purpose
Gateway Kong, Envoy, APISIX Centralized auth, rate limiting, routing
Testing 42Crunch, OWASP ZAP, Burp API security scanning, fuzzing
Governance Spectral, Optic, Redocly OpenAPI linting, breaking change detection
Discovery Treblle, Akto, Salt Security Shadow API detection, inventory

Rate Limiting Strategies

Fixed Window

100 requests per minute. Counter resets at minute boundary.

Simple but can allow burst at window edges

Sliding Window

Smooths rate over rolling time period.

Better distribution, more memory needed

Token Bucket

Tokens refill at fixed rate. Each request consumes a token.

Allows controlled bursting

Leaky Bucket

Requests queue and process at constant rate.

Smoothest output, adds latency

Circuit Breaker Pattern

Circuit breakers prevent cascade failures by stopping calls to failing services.

🟢

CLOSED

Normal operation. Requests pass through. Failures counted.

🔴

OPEN

Failure threshold exceeded. Requests fail fast. No calls to service.

🟡

HALF-OPEN

Testing recovery. Limited requests allowed. Success = close, failure = open.

API Security Checklist

  • ☐ All APIs require authentication
  • ☐ Authorization checked at resource level
  • ☐ Input validated against schema
  • ☐ Rate limiting configured per client tier
  • ☐ Response doesn't leak internal details
  • ☐ HTTPS only, TLS 1.2+
  • ☐ Security headers set (CORS, CSP for browser APIs)
  • ☐ API versioning strategy defined
  • ☐ Deprecation policy for old versions
  • ☐ Documentation doesn't expose vulnerabilities

Framework Alignment

OWASP: API Security Top 10 (2023), Application Security Verification Standard (ASVS) V13
NIST CSF 2.0: PR.AA (Identity & Access Control), PR.DS (Data Security)
ISO 27002:2022: A.8.26 (Application Security Requirements), A.8.28 (Secure Coding)
CIS Controls v8.1: 16 (Application Software Security), 13 (Network Monitoring & Defense)
Related: Security Frameworks →