The API Gateway as Security Perimeter


An API gateway acts as the single entry point for all client-to-service communication in a microservices architecture. It is uniquely positioned to enforce security policies centrally, reducing complexity in individual services and providing a consistent security layer.


Core Security Functions


Authentication and Authorization


The gateway validates tokens before requests reach backend services, offloading this responsibility from individual services.



# Kong Gateway authentication configuration

services:

  - name: user-service

    url: http://user-svc.internal:8080

    routes:

      - name: user-routes

        paths:

          - /api/users

    plugins:

      - name: jwt

        config:

          key_claim_name: iss

          secret_is_base64: false

          claims_to_verify:

            - exp

            - nbf

          run_on_preflight: true



// Custom auth middleware in Express Gateway

const jwt = require('jsonwebtoken');



async function gatewayAuth(req, res, next) {

    const token = req.headers.authorization?.replace('Bearer ', '');



    try {

        const decoded = jwt.verify(token, PUBLIC_KEY, {

            algorithms: ['RS256'],

            issuer: 'https://auth.example.com'

        });



        // Inject validated claims into downstream request

        req.headers['x-user-id'] = decoded.sub;

        req.headers['x-user-roles'] = decoded.roles.join(',');

        req.headers['x-authenticated'] = 'true';



        // Strip the original token from downstream

        delete req.headers.authorization;

        next();

    } catch (err) {

        return res.status(401).json({ error: 'Invalid token' });

    }

}


Rate Limiting and Throttling


The gateway enforces global and per-service rate limits:



plugins:

  - name: rate-limiting

    config:

      second: null

      minute: 1000

      hour: 50000

      policy: local

      fault_tolerant: true

      hide_client_headers: false

      redis:

        host: redis.internal

        port: 6379


IP Allowlisting and Blocklisting



plugins:

  - name: ip-restriction

    config:

      allow:

        - 10.0.0.0/8

        - 172.16.0.0/12

      deny:

        - 10.0.0.42  # Specific blocked IP


Request Validation


Schema Validation


Validate request bodies against OpenAPI schemas at the gateway:



plugins:

  - name: request-validator

    config:

      body_schema:

        type: object

        required:

          - email

          - password

        properties:

          email:

            type: string

            format: email

            maxLength: 255

          password:

            type: string

            minLength: 8

            maxLength: 128

      parameter_schema:

        - in: query

          name: page

          schema:

            type: integer

            minimum: 1


Request Size Limiting



# Nginx as API gateway

http {

    client_body_buffer_size 128k;

    client_max_body_size 10M;

    client_body_timeout 30s;



    server {

        listen 443 ssl;

        server_name api.example.com;



        location /api/ {

            # Limit request size per endpoint

            location /api/upload {

                client_max_body_size 100M;

            }



            location /api/query {

                client_max_body_size 1K;

            }

        }

    }

}


TLS Termination


Terminate TLS at the gateway to encrypt traffic between clients and the gateway, and optionally re-encrypt between gateway and services:



server {

    listen 443 ssl http2;

    server_name api.example.com;



    ssl_certificate /etc/ssl/certs/api.example.com.pem;

    ssl_certificate_key /etc/ssl/private/api.example.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;

    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;

    ssl_prefer_server_ciphers on;

    ssl_session_cache shared:SSL:10m;

    ssl_session_timeout 10m;



    # Backend communication (re-encrypt)

    location /api/internal/ {

        proxy_pass https://internal-services;

        proxy_ssl_verify on;

        proxy_ssl_trusted_certificate /etc/ssl/certs/ca.crt;

    }

}


CORS Management


Centrally manage CORS policies:



plugins:

  - name: cors

    config:

      origins:

        - https://app.example.com

        - https://admin.example.com

      methods:

        - GET

        - POST

        - PUT

        - DELETE

        - PATCH

      headers:

        - Authorization

        - Content-Type

      exposed_headers:

        - X-RateLimit-Remaining

      credentials: true

      max_age: 3600


Threat Detection and WAF


ModSecurity with OWASP CRS



# Enable WAF on the gateway

location /api/ {

    modsecurity on;

    modsecurity_rules_file /etc/nginx/modsecurity/owasp-crs/crs-setup.conf;



    # Custom rules

    modsecurity_rules '

        # Block SQL injection patterns

        SecRule REQUEST_URI "@rx (?i:(?:union[\s]+select|select[\s]+from))" \

            "id:1000,deny,status:403,msg:\'SQL Injection blocked\'"



        # Block common XSS attempts

        SecRule ARGS "@rx <script[^>]*>" \

            "id:1001,deny,status:403,msg:\'XSS blocked\'"



        # Rate limit login attempts

        SecRule IP:LOGIN_ATTEMPT "@gt 5" \

            "id:1002,deny,status:429,msg:\'Brute force blocked\'"

    ';

}


GraphQL Security at the Gateway


GraphQL APIs need specialized protections:



plugins:

  - name: graphql-proxy-cache

  - name: graphql-rate-limiting

    config:

      max_queries_per_minute: 100

      max_depth: 5

      max_complexity: 1000


Security Headers at the Gateway


Apply consistent security headers across all responses:



plugins:

  - name: response-transformer

    config:

      add:

        headers:

          - "Strict-Transport-Security: max-age=63072000; includeSubDomains; preload"

          - "X-Content-Type-Options: nosniff"

          - "X-Frame-Options: DENY"

          - "Content-Security-Policy: default-src 'self'"

          - "Referrer-Policy: strict-origin-when-cross-origin"


Audit Logging


Log all API requests centrally for security analysis:



plugins:

  - name: file-log

    config:

      path: /var/log/api-gateway/access.log

      custom_fields_by_lua:

        client_ip: "ngx.var.remote_addr"

        method: "ngx.var.request_method"

        path: "ngx.var.request_uri"

        status: "ngx.var.status"

        latency: "ngx.var.upstream_response_time"

        user_id: "ngx.var.http_x_user_id"


Summary


The API gateway is the ideal location to centralize security controls: authentication, rate limiting, request validation, IP restrictions, TLS termination, CORS management, and WAF rules. By enforcing these policies at the gateway, individual services remain simpler and can focus on business logic while maintaining a consistent security posture across your entire API surface.