Skip to main content

Kong Authentication System

Introduction

Authentication is a critical aspect of API security. It verifies the identity of clients attempting to access your services and ensures that only authorized users can interact with your APIs. Kong Gateway, a popular open-source API gateway, provides robust authentication mechanisms to protect your services.

In this tutorial, you'll learn how Kong's authentication system works and how to implement various authentication methods to secure your APIs. By the end of this guide, you'll be able to configure authentication for your microservices architecture using Kong.

What is Kong?

Kong is an open-source API gateway that sits in front of your APIs and microservices, handling cross-cutting concerns like:

  • Traffic control
  • Monitoring
  • Authentication
  • Rate limiting
  • Transformations

As an API gateway, Kong acts as a reverse proxy, routing client requests to appropriate backend services while applying policies like authentication.

Understanding Kong's Authentication Architecture

Kong's authentication system is plugin-based, giving you flexibility to choose the authentication method that best suits your needs.

Here's how Kong's authentication flow works:

When a request reaches Kong:

  1. Kong identifies which service/route the request is targeting
  2. It applies any configured authentication plugins
  3. If authentication passes, the request proceeds to the backend service
  4. If authentication fails, Kong returns a 401 Unauthorized response

Kong Authentication Plugins

Kong offers several authentication plugins. Let's explore the most commonly used ones:

1. Basic Authentication

Basic Authentication is the simplest form, using username and password credentials sent in the Authorization header.

Configuration

To enable Basic Authentication:

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

# Create a route
$ 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=john"

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

Making Authenticated Requests

bash
# This will fail with 401
$ curl -i http://localhost:8000/api

# This will succeed
$ curl -i http://localhost:8000/api \
-H "Authorization: Basic $(echo -n 'john:secret' | base64)"

2. Key Authentication

Key Authentication (also called API key authentication) uses a key that is unique to each consumer.

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 Consumers and 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-secret-api-key"

Making Authenticated Requests

bash
# Using query parameter
$ curl -i http://localhost:8000/api?apikey=your-secret-api-key

# Using header
$ curl -i http://localhost:8000/api \
-H "apikey: your-secret-api-key"

3. JWT Authentication

JSON Web Tokens (JWT) provide a more secure authentication method, especially for single-page applications and microservices.

Configuration

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

Creating Consumers and Credentials

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

# Create JWT credentials
$ curl -i -X POST http://localhost:8001/consumers/mobile-app/jwt \
--data "algorithm=HS256" \
--data "key=mobile-app-key"

The response will include a secret that you'll use to sign your JWTs.

Making Authenticated Requests

First, generate a JWT using the key and secret. Many libraries are available for this. Here's a simplified example:

javascript
// Node.js example using jsonwebtoken library
const jwt = require('jsonwebtoken');

const payload = {
iss: 'mobile-app-key' // The "key" field from your JWT credentials
};

const token = jwt.sign(payload, 'your-jwt-secret', { algorithm: 'HS256' });
console.log(token); // Use this token in your API request

Then use the token in your request:

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

4. OAuth 2.0 Authentication

For more complex scenarios, Kong supports OAuth 2.0 authentication flow.

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 2.0 is more complex and involves multiple steps:

  1. Creating a consumer
  2. Creating an application
  3. Implementing the authorization flow
  4. Managing access tokens

Due to its complexity, we'll explore OAuth 2.0 in a separate, dedicated tutorial.

Combining Authentication Methods

Kong allows you to combine multiple authentication plugins. For instance, you might want to:

  • Use JWT for your mobile app
  • Use API keys for your partner integrations
  • Use Basic Auth for admin tools

To implement this, you can configure multiple authentication plugins on different routes:

bash
# JWT for mobile app route
$ curl -i -X POST http://localhost:8001/services/example-service/routes \
--data "paths[]=/api/mobile" \
--data "name=mobile-route"

$ curl -i -X POST http://localhost:8001/routes/mobile-route/plugins/ \
--data "name=jwt"

# Key Auth for partner API routes
$ curl -i -X POST http://localhost:8001/services/example-service/routes \
--data "paths[]=/api/partners" \
--data "name=partner-route"

$ curl -i -X POST http://localhost:8001/routes/partner-route/plugins/ \
--data "name=key-auth"

Real-World Example: Securing a Microservices Architecture

Let's look at a practical example of securing multiple services in a microservices architecture:

Implementation Steps

  1. Set up your services in Kong:
bash
# User service
$ curl -i -X POST http://localhost:8001/services/ \
--data "name=user-service" \
--data "url=http://user-service:3000"

$ curl -i -X POST http://localhost:8001/services/user-service/routes \
--data "paths[]=/api/users"

# Product service
$ curl -i -X POST http://localhost:8001/services/ \
--data "name=product-service" \
--data "url=http://product-service:3001"

$ curl -i -X POST http://localhost:8001/services/product-service/routes \
--data "paths[]=/api/products"

# Admin service
$ curl -i -X POST http://localhost:8001/services/ \
--data "name=admin-service" \
--data "url=http://admin-service:3002"

$ curl -i -X POST http://localhost:8001/services/admin-service/routes \
--data "paths[]=/api/admin"
  1. Apply authentication plugins to each service:
bash
# JWT for user service
$ curl -i -X POST http://localhost:8001/services/user-service/plugins/ \
--data "name=jwt"

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

# Basic Auth for admin service
$ curl -i -X POST http://localhost:8001/services/admin-service/plugins/ \
--data "name=basic-auth"
  1. Create consumers and credentials for each service

This follows the patterns we've already discussed for each authentication type.

Best Practices for Kong Authentication

  1. Use HTTPS - Always use HTTPS in production to protect credentials in transit
  2. Rotate credentials regularly - Implement a process to rotate API keys and secrets
  3. Apply rate limiting - Combine authentication with rate limiting to prevent brute force attacks
  4. Monitor failed authentication attempts - Set up logging and alerts for repeated authentication failures
  5. Use the principle of least privilege - Grant only the permissions necessary for each consumer
  6. Consider ACL plugins - After authentication, use Access Control Lists to further control access
  7. Implement JWT token expiration - For JWT authentication, set reasonable expiration times
  8. Don't expose consumer IDs - Use the hide_credentials option when available

Troubleshooting Authentication Issues

Common Issues and Solutions

  1. 401 Unauthorized errors:

    • Verify the credentials are correct
    • Check if the consumer exists
    • Ensure the plugin is configured correctly
  2. Credentials not being recognized:

    • Verify the format of the Authorization header
    • For JWT, check that the token is properly signed
    • For API keys, ensure the key name matches the configuration
  3. Plugin configuration issues:

    • Use curl -i -X GET http://localhost:8001/services/your-service/plugins to check plugin status
    • Review Kong logs for detailed error information

Debugging Tips

Enable verbose logging in Kong by updating your Kong configuration:

yaml
# In kong.conf
log_level = debug

Then check the logs:

bash
$ tail -f /usr/local/kong/logs/error.log

Summary

In this tutorial, you've learned:

  • How Kong's authentication system works at a high level
  • How to configure different authentication plugins (Basic Auth, Key Auth, JWT)
  • How to create consumers and credentials
  • How to make authenticated requests to your APIs
  • How to implement authentication in a microservices architecture
  • Best practices for API authentication with Kong

Kong's flexible authentication system allows you to implement the right security model for your specific needs, whether you're building a simple API or a complex microservices architecture.

Additional Resources

Exercises

  1. Set up Kong locally and configure Basic Authentication for a simple API
  2. Create a consumer and test authentication with curl
  3. Implement JWT authentication for a different route
  4. Try combining multiple authentication methods for a single service
  5. Implement a simple frontend that authenticates with your Kong-protected API


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