Kong Basic Auth
Introduction
Basic Authentication is one of the simplest and most widely used authentication methods for securing APIs. Kong, a popular API Gateway, provides a powerful Basic Auth plugin that allows you to quickly implement this security mechanism for your services.
In this guide, we'll explore how to set up, configure, and use Basic Authentication in Kong to protect your APIs from unauthorized access.
What is Basic Authentication?
Basic Authentication is an HTTP authentication scheme that requires a username and password to access protected resources. When a client makes a request to a protected endpoint, it must include an Authorization
header with a Base64-encoded string of the username and password in the format username:password
.
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
While simple to implement, Basic Auth has some inherent limitations:
- Credentials are only encoded (not encrypted) and can be decoded easily
- Credentials are sent with every request, increasing exposure risk
- No built-in mechanism for token expiration or revocation
Despite these limitations, Basic Auth remains useful for development environments, internal services, or as a simple first layer of security when combined with HTTPS.
How Kong Basic Auth Works
When you enable the Basic Auth plugin in Kong, it will:
- Intercept incoming requests to your API
- Check for the presence of valid Basic Authentication credentials
- Validate these credentials against configured users
- Either allow the request to proceed or reject it with a 401 Unauthorized response
Setting Up Basic Auth in Kong
Let's go through the process of implementing Basic Auth in Kong step by step.
Prerequisites
- Kong installed and running
- Kong Admin API accessible
- A service already configured in Kong
Step 1: Create a Service and Route
First, let's ensure we have a service and route set up in Kong. If you already have these configured, you can skip to Step 2.
# Create a service
curl -i -X POST http://localhost:8001/services \
--data "name=example-service" \
--data "url=http://example-api.com"
# Create a route for the service
curl -i -X POST http://localhost:8001/services/example-service/routes \
--data "name=example-route" \
--data "paths[]=/api"
Step 2: Enable the Basic Auth Plugin
Now, let's enable the Basic Auth plugin for our service:
curl -i -X POST http://localhost:8001/services/example-service/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true"
The hide_credentials
option (set to true
here) prevents Kong from forwarding the credentials to your upstream service.
Step 3: Create Consumers
Consumers in Kong represent the users or applications that will access your API. Let's create a consumer:
curl -i -X POST http://localhost:8001/consumers \
--data "username=john"
Step 4: Create Credentials for Consumers
Now, let's create Basic Auth credentials for our consumer:
curl -i -X POST http://localhost:8001/consumers/john/basic-auth \
--data "username=john" \
--data "password=secret123"
Step 5: Test the Configuration
With everything set up, let's test our Basic Auth configuration:
# This request should fail with a 401 Unauthorized
curl -i http://localhost:8000/api
# This request should succeed
curl -i http://localhost:8000/api \
-H "Authorization: Basic $(echo -n 'john:secret123' | base64)"
Configuration Options
The Basic Auth plugin supports several configuration options:
Option | Description | Default |
---|---|---|
hide_credentials | Prevents the credentials from being sent to the upstream service | false |
anonymous | An optional consumer id to use when authentication fails | null |
realm | Defines the protection realm | kong |
Advanced Configuration Example
Let's set up a more advanced configuration that allows anonymous access to certain endpoints:
# Create an anonymous consumer
curl -i -X POST http://localhost:8001/consumers \
--data "username=anonymous"
# Enable Basic Auth with anonymous consumer
curl -i -X POST http://localhost:8001/services/example-service/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true" \
--data "config.anonymous=$(curl -s http://localhost:8001/consumers/anonymous | jq -r '.id')"
With this setup, requests without authentication will be processed as the "anonymous" consumer, which could have limited permissions set by other plugins.
Real-World Examples
Protecting an Admin Dashboard
Let's say you have an admin dashboard that needs protection:
# Create admin service and route
curl -i -X POST http://localhost:8001/services \
--data "name=admin-dashboard" \
--data "url=http://internal.example.com/admin"
curl -i -X POST http://localhost:8001/services/admin-dashboard/routes \
--data "name=admin-route" \
--data "paths[]=/admin"
# Enable Basic Auth with strict settings
curl -i -X POST http://localhost:8001/services/admin-dashboard/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true"
# Create admin consumer and credentials
curl -i -X POST http://localhost:8001/consumers \
--data "username=admin"
curl -i -X POST http://localhost:8001/consumers/admin/basic-auth \
--data "username=admin" \
--data "password=strong_password_here"
API with Mixed Authentication Requirements
For APIs with mixed authentication requirements (some endpoints public, others protected):
# Create API service
curl -i -X POST http://localhost:8001/services \
--data "name=mixed-api" \
--data "url=http://api.example.com"
# Create public route
curl -i -X POST http://localhost:8001/services/mixed-api/routes \
--data "name=public-route" \
--data "paths[]=/api/public"
# Create protected route
curl -i -X POST http://localhost:8001/services/mixed-api/routes \
--data "name=protected-route" \
--data "paths[]=/api/protected"
# Apply Basic Auth only to the protected route
curl -i -X POST http://localhost:8001/routes/protected-route/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true"
Integrating with Front-End Applications
When calling a Kong-protected API from JavaScript, you can set up your API calls like this:
// Function to call a protected API
async function callProtectedApi(endpoint, username, password) {
// Create Base64 encoded credentials
const credentials = btoa(`${username}:${password}`);
try {
const response = await fetch(`https://api.example.com${endpoint}`, {
method: 'GET',
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Error calling API:', error);
throw error;
}
}
// Usage
callProtectedApi('/protected-resource', 'john', 'secret123')
.then(data => console.log('API response:', data))
.catch(error => console.error('API call failed:', error));
Best Practices
To use Basic Auth securely in production environments:
-
Always use HTTPS: Basic Auth credentials are sent in an encoded but not encrypted format. HTTPS is essential to prevent credential interception.
-
Implement IP restrictions: Consider adding IP restriction plugins in Kong to limit which IP addresses can access your APIs.
-
Use strong passwords: Enforce strong password policies for all credentials.
-
Regular credential rotation: Change credentials periodically to reduce risk.
-
Consider more advanced authentication: For production systems, consider combining Basic Auth with other authentication methods or using more secure alternatives like OAuth 2.0 or JWT.
-
Limit credential exposure: Use the
hide_credentials=true
option to prevent credential exposure to backend services.
Troubleshooting
401 Unauthorized Errors
If you're getting 401 errors:
- Check that your Base64 encoding is correct
- Verify the consumer and credentials exist in Kong
- Make sure the Authorization header is formatted correctly
- Check Kong logs for more details about the authentication failure
Performance Considerations
Basic Auth validation adds a small overhead to each request. For high-traffic APIs, consider:
- Implementing caching strategies
- Monitoring Kong performance
- Using a more efficient authentication method for high-volume endpoints
Summary
Kong's Basic Auth plugin provides a simple yet effective way to protect your APIs:
- Easy to implement and understand
- Works with any HTTP client
- Configurable with options for anonymous access and credential hiding
- Integrates well with Kong's other security plugins
While Basic Auth has limitations for high-security environments, it's an excellent starting point for API security and a good solution for internal or development APIs.
Additional Resources
- Kong's official Basic Auth plugin documentation
- HTTP authentication specification (RFC 7617)
- Web security best practices guides
Exercises
- Set up Kong with Basic Auth to protect a simple API of your choice.
- Create multiple consumers with different credentials.
- Implement a system where some endpoints require authentication and others don't.
- Try combining Basic Auth with rate limiting to create a more comprehensive security solution.
- Create a simple front-end application 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! :)