The API Gateway pattern implements a service that’s the entry point into a microservices-based application from external API clients or consumers. It is responsible for request routing, API composition, and other edge functions, such as authentication.
When working with a microservices architecture, either on a greenfield project or during migration from a monolith, a best practice is to start addressing cross-cutting concerns. Authentication is such a concern, and in this article, we’ll cover the authentication of a multi-tenancy application.
There are numerous technologies we can use to implement an API Gateway pattern, including off-the-shelf API Gateway products, like Kong.
API Gateway workflow When it receives a request, Kong searches within a routing map that specifies which upstream service to route the request to. This function is identical to the reverse proxy feature provided by web servers, such as NGINX. Kong is based on the NGINX HTTP server, and lets us configure flexible routing rules that use the HTTP method, headers, and path to select the backend/upstream service; it also provides a bundle of plugins that implement edge functions.
You may also like: API Gateway to the Rescue.
Let’s consider the following prerequisites and steps to implement API key-based authentication:
- myService — A microservice that should be private and exposes an endpoint: http://myServicePrivateHost:80/api/v1/myServicePath
- Two tenants — tenant1.mydomain.com and tenant2.mydomain.com, for which we want to authenticate the requests.
- Kong running on http://localhost:8000 for proxying and http://localhost:8001 for Admin API.
1. Create a Service Object, a Representation of the Upstream Microservice
2. Create a Route Object for Each Tenant
- Service id — Is extracted from step 1’s response.
- Hosts — Field containing the actual domain, tenant specific.
- Route name — Must be unique, and in this case, it is prefixed with the tenant name.
Note: Perform the same request from the current step and replace tenant1 with tenant2 for the purpose of creating the route for the other tenant.
When a request comes in, Kong will make use of the host header, path, and HTTP method in order to select the route. If no route is found, the response will be:
At this point we have two unauthenticated routes and we’ll create a consumer for each of them. Those consumers can be client applications or users and they can have multiple api keys.
3. Create a Consumer Object for Each Tenant
Note: Perform the same request from the current step and replace tenant1 with tenant2 for the purpose of creating the consumer for the other tenant.
Now, we should group the consumers for a specific tenant (there are also cases where we want to group by a tenant’s application as well), and the specified group name will be whitelisted for consuming the API.
4. Create a Group for Each Consumer
Note: Perform the same request from the current step and replace tenant1 with tenant2 to create the group for the other tenant.
5. Applying Key-Auth Plugin for the Tenant-Specific Route
Note: Perform the same request from the current step and replace tenant1 with tenant2 for the purpose of applying the plugin for the other tenant route.
6. Applying acl Plugin for the Tenant-Specific Route
Note: Perform the same request from the current step and replace tenant1 with tenant2 to apply the plugin for the other tenant route.
7. Generate an API Key for Tenant1
8. Access /api/v1/myServicePath for Tenant1 Without an API Key Header:
9. Access /api/v1/myServicePath for Tenant1 With the Corresponding API Key Generated in Step 7
Note: The response depends on the actual microservice deployed locally. If it’s up and running it will return the proper response. In our case the service doesn’t exist so it will return 503 service temporary unavailable and the above response.
10. Access /api/v1/myServicePath for Tenant2 With Tenant1’s API Key
These steps can be further automated by creating a wrapper over Kong Admin API. It will be in fact a microservice other services (e.g an IAM — Identity and access management — microservice responsible for authentication and authorization) will communicate with, as a means to generate consumers and API keys for those consumers.
In this way, we can leverage Kong API Gateway for centralizing the authentication to our multi-tenancy application.