Skip to main content

Kong Security Best Practices

Introduction

Kong is a popular, open-source API gateway that helps manage, secure, and extend APIs. As APIs become the standard way of connecting services and applications, securing these pathways becomes crucial. This guide focuses on essential security best practices when using Kong API Gateway to protect your APIs from common threats and vulnerabilities.

Whether you're deploying Kong in a development environment or a production setting, implementing these security measures will help you build a robust security posture for your API infrastructure.

Core Security Concepts in Kong

Before diving into specific best practices, let's understand the core security concepts in Kong:

  1. Authentication: Verifying the identity of clients accessing your APIs
  2. Authorization: Determining what resources authenticated clients can access
  3. Rate Limiting: Protecting APIs from abuse by limiting request volumes
  4. Request/Response Transformation: Modifying requests and responses to eliminate security risks
  5. Logging and Monitoring: Tracking API activity to detect and respond to suspicious behavior

Setting Up Secure Kong Deployments

Secure Installation Best Practices

When setting up Kong, follow these security-focused installation steps:

bash
# Use specific versions rather than 'latest' to avoid unexpected changes
$ kong config -c kong.conf --v prepare
$ kong migrations bootstrap
# Run Kong with minimal privileges
$ kong start -c kong.conf

Ensure your kong.conf file includes these security-focused settings:

# Disable the Admin API on public interfaces
admin_listen = 127.0.0.1:8001

# Enable HTTPS for Admin API
admin_ssl_cert = /path/to/admin_ssl.cert
admin_ssl_cert_key = /path/to/admin_ssl.key

# Enforce HTTPS for proxy
proxy_ssl_cert = /path/to/proxy_ssl.cert
proxy_ssl_cert_key = /path/to/proxy_ssl.key

# Set strict security headers
headers = server_tokens=off

Network Security Configuration

Authentication and Authorization

Implementing Strong Authentication

Kong provides several authentication plugins. Here's how to implement the JWT (JSON Web Token) authentication plugin:

bash
# Create a service
$ curl -i -X POST http://localhost:8001/services/ \
--data "name=my-service" \
--data "url=http://my-upstream-service.com"

# Create a route for the service
$ curl -i -X POST http://localhost:8001/services/my-service/routes \
--data "paths[]=/api"

# Enable the JWT plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=jwt"

After configuring the JWT plugin, clients must include a valid JWT in their requests:

bash
# Example of a client request with JWT authentication
$ curl -i -X GET http://kong:8000/api \
--header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"

Implementing OAuth 2.0

For more advanced authentication scenarios, Kong's OAuth 2.0 plugin provides a complete OAuth 2.0 server implementation:

bash
# Enable the OAuth 2.0 plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=oauth2" \
--data "config.enable_authorization_code=true" \
--data "config.mandatory_scope=true" \
--data "config.global_credentials=false" \
--data "config.scopes=email,phone,address" \
--data "config.token_expiration=7200"

With this configuration, clients must first obtain an access token before accessing the protected API:

bash
# Request an authorization code
$ curl -i -X POST http://kong:8000/oauth2/authorize \
--data "client_id=CLIENT_ID" \
--data "response_type=code" \
--data "scope=email"

# Exchange the authorization code for an access token
$ curl -i -X POST http://kong:8000/oauth2/token \
--data "grant_type=authorization_code" \
--data "code=AUTHORIZATION_CODE" \
--data "client_id=CLIENT_ID" \
--data "client_secret=CLIENT_SECRET"

# Use the access token to access the API
$ curl -i -X GET http://kong:8000/api \
--header "Authorization: Bearer ACCESS_TOKEN"

Implementing Rate Limiting

Rate limiting helps protect your APIs from abuse and denial of service attacks:

bash
# Add rate limiting to a service
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=rate-limiting" \
--data "config.second=5" \
--data "config.hour=10000" \
--data "config.policy=local"

This configuration limits clients to 5 requests per second and 10,000 requests per hour.

Advanced Rate Limiting with Redis

For distributed deployments, use Redis to synchronize rate limiting across Kong nodes:

bash
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=rate-limiting" \
--data "config.second=5" \
--data "config.hour=10000" \
--data "config.policy=redis" \
--data "config.redis_host=redis-server" \
--data "config.redis_port=6379" \
--data "config.redis_timeout=2000"

API Key Security

Protect your APIs with API key authentication:

bash
# Enable the key-auth plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=key-auth" \
--data "config.key_names=apikey" \
--data "config.hide_credentials=true"

# Create a consumer
$ curl -X POST http://localhost:8001/consumers/ \
--data "username=consumer1"

# Provision an API key for the consumer
$ curl -X POST http://localhost:8001/consumers/consumer1/key-auth \
--data "key=SECURE_API_KEY"

With this configuration, clients must include the API key in their requests:

bash
# Example request with API key
$ curl -i -X GET http://kong:8000/api \
--header "apikey: SECURE_API_KEY"

IP Restriction

Limit API access to trusted IP addresses:

bash
# Allow only specific IP addresses
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=ip-restriction" \
--data "config.allow=192.168.1.0/24,10.0.0.0/8"

SSL/TLS Configuration

Enforcing HTTPS

Always enforce HTTPS for your APIs to prevent man-in-the-middle attacks:

bash
# Enable HTTPS enforcement with the SSL plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=ssl" \
--data "config.cert=/path/to/cert.pem" \
--data "config.key=/path/to/key.pem" \
--data "config.only_https=true"

Alternatively, configure Kong to redirect HTTP to HTTPS:

yaml
# kong.yml configuration
plugins:
- name: request-transformer
config:
http_method: GET
remove:
headers:
- Host
replace:
uri: $(uri:gsub("^http://", "https://"))

Regular Security Audits

Regularly audit your Kong configuration using the Admin API:

bash
# List all plugins to review security configurations
$ curl -s http://localhost:8001/plugins | jq

# Check for exposed services without authentication
$ curl -s http://localhost:8001/services | jq '.data[] | {name, plugins: .plugins.data[].name}'

# Review rate limiting configurations
$ curl -s http://localhost:8001/plugins?name=rate-limiting | jq

Monitoring and Logging

Setting Up Comprehensive Logging

Configure Kong to log detailed information for security monitoring:

bash
# Enable HTTP Log plugin to send logs to an external system
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=http-log" \
--data "config.http_endpoint=http://logger:3000/logs" \
--data "config.method=POST" \
--data "config.timeout=10000" \
--data "config.keepalive=60000"

Integrating with Security Information and Event Management (SIEM)

For enterprise environments, integrate Kong logs with your SIEM system:

bash
# Enable TCP Log plugin for SIEM integration
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=tcp-log" \
--data "config.host=siem-server" \
--data "config.port=5140"

Request and Response Transformation

Enhance security by transforming requests and responses:

bash
# Remove sensitive headers from requests
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=request-transformer" \
--data "config.remove.headers=Authorization,Cookie"

# Add security headers to responses
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=response-transformer" \
--data "config.add.headers=Strict-Transport-Security:max-age=31536000; includeSubDomains,X-Content-Type-Options:nosniff,X-Frame-Options:DENY"

Advanced Security with Kong Enterprise

If you're using Kong Enterprise, additional security features are available:

OpenID Connect Integration

bash
# Enable the OpenID Connect plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=openid-connect" \
--data "config.issuer=https://accounts.google.com/.well-known/openid-configuration" \
--data "config.client_id=YOUR_CLIENT_ID" \
--data "config.client_secret=YOUR_CLIENT_SECRET" \
--data "config.scopes=openid,email,profile" \
--data "config.verify_parameters=false"

Role-Based Access Control (RBAC)

bash
# Create a role
$ curl -X POST http://localhost:8001/rbac/roles \
--data "name=read-only"

# Add permissions to the role
$ curl -X POST http://localhost:8001/rbac/roles/read-only/endpoints \
--data "endpoint=*" \
--data "actions=read"

# Assign the role to a user
$ curl -X POST http://localhost:8001/rbac/users \
--data "name=user123" \
--data "user=user123" \
--data "roles=read-only"

Common Pitfalls and How to Avoid Them

  1. Exposing the Admin API: Always restrict access to the Admin API by binding it to localhost or using network controls.

  2. Using Default Configurations: Kong's default configurations prioritize ease of use over security. Always customize settings with security in mind.

  3. Overlooking Rate Limiting: Implement rate limiting for all services to prevent abuse.

  4. Inadequate Monitoring: Set up comprehensive logging and monitor for unusual patterns or security incidents.

  5. Neglecting Regular Updates: Keep Kong and its plugins updated to protect against known vulnerabilities.

Security Checklist for Kong Deployments

Use this checklist to ensure your Kong deployment follows security best practices:

  • Admin API is secured and not publicly accessible
  • HTTPS is enforced for all API traffic
  • Authentication is enabled for all services
  • Rate limiting is configured appropriately
  • IP restrictions are applied where needed
  • Logging and monitoring are properly set up
  • Security headers are added to responses
  • Kong and plugins are regularly updated
  • Regular security audits are performed
  • Sensitive data is not exposed in logs

Summary

Implementing these Kong security best practices helps protect your APIs from common threats while ensuring your services remain available and performant. Remember that security is an ongoing process that requires regular reviews and updates as your API infrastructure evolves.

By following these guidelines, you'll establish a solid security foundation for your Kong API Gateway deployment and build more secure, robust API services.

Additional Resources

Practice Exercises

  1. Set up a Kong gateway with JWT authentication and test it using curl commands.
  2. Configure rate limiting with Redis and test how it behaves under high load.
  3. Create a security audit script that checks your Kong configuration for common misconfigurations.
  4. Implement request and response transformations to enhance the security of an existing API.
  5. Set up a comprehensive monitoring solution for your Kong deployment to detect potential security incidents.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)