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.
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:
- Extracts credentials from the request (header, query params, etc.)
- Validates these credentials against configured values or external systems
- 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:
# 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
# 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
# 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
# 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
# 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
# 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
# Enable jwt plugin
$ curl -i -X POST http://localhost:8001/services/example-service/plugins/ \
--data "name=jwt"
Creating a JWT Credential
# 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:
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:
$ curl -i http://localhost:8000/api \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
OAuth 2.0 Authentication
For applications requiring delegated authentication and authorization flows.
Configuration
# 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
# 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:
# 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
- Set up Kong Gateway in front of all your microservices
- Configure Routes for each service:
# 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"
- Apply Different Authentication Methods based on service sensitivity:
# 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"
- 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
- Use HTTPS: Always use TLS/SSL with Kong to encrypt credentials in transit
- Rate Limiting: Combine authentication with rate limiting to prevent brute force attacks
- Rotate Credentials: Establish a process for regular credential rotation
- Least Privilege: Give consumers access only to the specific routes they need
- Audit Logging: Enable request/response logging for security audits
- Monitor Failed Attempts: Set up alerts for unusual authentication failure patterns
# 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:
- Verify the credentials are correct
- Check that the consumer exists
- Ensure the authentication header format is correct
- Check Kong logs for detailed error information
# 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:
- Verify plugin configuration with:
$ curl -i http://localhost:8001/services/example-service/plugins
- Check that the plugin is enabled globally:
$ 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
- Set up a basic Kong gateway with the basic-auth plugin and create a consumer with credentials
- Implement API key authentication for a service and test it with both header and query parameter methods
- Create a JWT authentication system and write a simple client that generates valid tokens
- 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! :)