Skip to main content

Kong Authentication

Introduction

Authentication is a critical component of API security, ensuring that only authorized clients can access your services. Kong, a popular open-source API gateway, provides several authentication plugins that make implementing robust security straightforward and flexible.

In this guide, we'll explore how Kong's authentication plugins work, how to configure them, and demonstrate their use through practical examples. Whether you're building a small application or managing enterprise-level APIs, understanding Kong's authentication options will help you secure your services effectively.

What is Kong Authentication?

Kong authentication refers to the various methods and plugins provided by Kong API Gateway to verify the identity of clients attempting to access your APIs. These plugins act as a security layer that sits between client requests and your backend services.

Why use Kong for authentication?

By implementing authentication at the API gateway level rather than in each service, you create a centralized security model that is easier to manage, audit, and update.

How Kong Authentication Works

At a high level, Kong authentication follows this flow:

When a request reaches Kong, the configured authentication plugin:

  1. Extracts credentials from the request (header, query params, etc.)
  2. Validates these credentials against configured values or external systems
  3. Either allows the request to proceed to your API or returns an error response

Common Authentication Plugins

Kong offers several authentication plugins to suit different security requirements:

Basic Authentication

The simplest form of authentication, where clients provide a username and password with each request.

Configuration

To enable Basic Authentication:

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

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

# Enable basic-auth plugin
$ curl -i -X POST http://localhost:8001/services/example-service/plugins/ \
--data "name=basic-auth" \
--data "config.hide_credentials=true"

Creating Consumers and Credentials

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

# Create credentials for the consumer
$ curl -i -X POST http://localhost:8001/consumers/user123/basic-auth \
--data "username=user123" \
--data "password=password123"

Making Authenticated Requests

bash
# Request without authentication (will fail)
$ curl -i http://localhost:8000/api

# Request with authentication
$ curl -i http://localhost:8000/api \
-H "Authorization: Basic $(echo -n 'user123:password123' | base64)"

The server response will vary depending on authentication success:

# Successful authentication
HTTP/1.1 200 OK
...

# Failed authentication
HTTP/1.1 401 Unauthorized
...
{"message":"Unauthorized"}

Key Authentication (API Key)

A common authentication method where clients include an API key with each request.

Configuration

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

Creating Keys

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

# Create an API key for the consumer
$ curl -i -X POST http://localhost:8001/consumers/app1/key-auth \
--data "key=your-api-key-here"

Making Authenticated Requests

bash
# As a header
$ curl -i http://localhost:8000/api \
-H "apikey: your-api-key-here"

# Or as a query parameter
$ curl -i http://localhost:8000/api?apikey=your-api-key-here

JWT Authentication

JSON Web Tokens provide a more sophisticated authentication mechanism, especially useful for single sign-on scenarios.

Configuration

bash
# Enable jwt plugin
$ curl -i -X POST http://localhost:8001/services/example-service/plugins/ \
--data "name=jwt"

Creating a JWT Credential

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

# Create a JWT credential
$ curl -i -X POST http://localhost:8001/consumers/user456/jwt \
--data "algorithm=HS256" \
--data "key=user-jwt-key"
--data "secret=jwt-secret-here"

Making Authenticated Requests

First, generate a JWT token using your preferred JWT library. Here's a Node.js example:

javascript
const jwt = require('jsonwebtoken');

// Create token
const token = jwt.sign({
iss: 'user-jwt-key' // The 'key' value from credential creation
}, 'jwt-secret-here', {
algorithm: 'HS256',
expiresIn: '1h'
});

console.log(token);

Then use the token in your request:

bash
$ curl -i http://localhost:8000/api \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

OAuth 2.0 Authentication

For applications requiring delegated authentication and authorization flows.

Configuration

bash
# Enable oauth2 plugin
$ curl -i -X POST http://localhost:8001/services/example-service/plugins/ \
--data "name=oauth2" \
--data "config.enable_authorization_code=true" \
--data "config.scopes=email,profile" \
--data "config.mandatory_scope=true"

Setting Up OAuth Application

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

# Create an OAuth application
$ curl -i -X POST http://localhost:8001/consumers/app2/oauth2 \
--data "name=My App" \
--data "client_id=client-id-here" \
--data "client_secret=client-secret-here" \
--data "redirect_uris[]=https://example.com/callback"

The OAuth 2.0 flow involves several steps including authorization, token exchange, and authenticated API calls. The full implementation is beyond this basic guide, but follows standard OAuth 2.0 protocols.

Combining Authentication Plugins

Kong allows you to use multiple authentication plugins on the same service, giving clients flexibility in how they authenticate:

bash
# Enable both basic-auth and key-auth for the same service
$ curl -i -X POST http://localhost:8001/services/example-service/plugins/ \
--data "name=basic-auth"

$ curl -i -X POST http://localhost:8001/services/example-service/plugins/ \
--data "name=key-auth"

With this configuration, clients can authenticate using either method.

Real-World Example: Securing a Microservice Architecture

Let's look at a practical example of securing a microservice architecture with Kong authentication:

Implementation Steps

  1. Set up Kong Gateway in front of all your microservices
  2. Configure Routes for each service:
bash
# Create services
$ curl -X POST http://localhost:8001/services --data "name=user-service" --data "url=http://user-service:3000"
$ curl -X POST http://localhost:8001/services --data "name=product-service" --data "url=http://product-service:3001"
$ curl -X POST http://localhost:8001/services --data "name=payment-service" --data "url=http://payment-service:3002"
$ curl -X POST http://localhost:8001/services --data "name=admin-service" --data "url=http://admin-service:3003"

# Create routes
$ curl -X POST http://localhost:8001/services/user-service/routes --data "paths[]=/users"
$ curl -X POST http://localhost:8001/services/product-service/routes --data "paths[]=/products"
$ curl -X POST http://localhost:8001/services/payment-service/routes --data "paths[]=/payments"
$ curl -X POST http://localhost:8001/services/admin-service/routes --data "paths[]=/admin"
  1. Apply Different Authentication Methods based on service sensitivity:
bash
# JWT for user service
$ curl -X POST http://localhost:8001/services/user-service/plugins --data "name=jwt"

# Key auth for product service
$ curl -X POST http://localhost:8001/services/product-service/plugins --data "name=key-auth"

# OAuth2 for payment service
$ curl -X POST http://localhost:8001/services/payment-service/plugins --data "name=oauth2" --data "config.enable_authorization_code=true"

# Basic auth for admin service
$ curl -X POST http://localhost:8001/services/admin-service/plugins --data "name=basic-auth"
  1. Create Consumers for different client applications, and generate appropriate credentials for each

This approach provides layered security appropriate to each service's requirements.

Best Practices for Kong Authentication

  1. Use HTTPS: Always use TLS/SSL with Kong to encrypt credentials in transit
  2. Rate Limiting: Combine authentication with rate limiting to prevent brute force attacks
  3. Rotate Credentials: Establish a process for regular credential rotation
  4. Least Privilege: Give consumers access only to the specific routes they need
  5. Audit Logging: Enable request/response logging for security audits
  6. Monitor Failed Attempts: Set up alerts for unusual authentication failure patterns
bash
# Example: Adding rate limiting to authenticated endpoints
$ curl -i -X POST http://localhost:8001/services/example-service/plugins/ \
--data "name=rate-limiting" \
--data "config.minute=100" \
--data "config.policy=local"

Troubleshooting Common Issues

Authentication Failures

If requests are being rejected with 401 errors:

  1. Verify the credentials are correct
  2. Check that the consumer exists
  3. Ensure the authentication header format is correct
  4. Check Kong logs for detailed error information
bash
# View Kong logs
$ kubectl logs -f deployment/kong -n kong

# Test a credential directly against Admin API
$ curl -i http://localhost:8001/consumers/username/basic-auth

Plugin Configuration Issues

If the plugin isn't working as expected:

  1. Verify plugin configuration with:
bash
$ curl -i http://localhost:8001/services/example-service/plugins
  1. Check that the plugin is enabled globally:
bash
$ curl -i http://localhost:8001/plugins/enabled

Summary

Kong's authentication plugins provide a flexible, centralized approach to securing your APIs. By implementing authentication at the gateway level, you can:

  • Standardize security across all services
  • Manage credentials in a single place
  • Apply different authentication methods based on service requirements
  • Free your backend services from authentication concerns

The choice of authentication method depends on your specific requirements, but Kong's plugin architecture makes it easy to implement and maintain robust API security regardless of which method you choose.

Additional Resources

Exercises

  1. Set up a basic Kong gateway with the basic-auth plugin and create a consumer with credentials
  2. Implement API key authentication for a service and test it with both header and query parameter methods
  3. Create a JWT authentication system and write a simple client that generates valid tokens
  4. Design a microservice architecture that uses different authentication methods for different types of services


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