Securing Quarkus Microservices via Kong API Gateway

by Didin J. on May 24, 2025 Securing Quarkus Microservices via Kong API Gateway

Secure Quarkus microservices with Kong API Gateway using Docker, key-auth, rate limiting, and dynamic API key management for modern microservice security

Building fast and scalable applications is no longer enough in today's cloud-native and microservices-driven world — securing those applications is equally critical. As developers decompose monoliths into distributed microservices, they face new challenges around security, traffic management, authentication, and observability.

This is where an API Gateway becomes essential.

Kong is a popular, open-source API gateway and microservice management layer. It acts as a single entry point for all incoming API traffic, providing powerful features like rate limiting, authentication, logging, and traffic transformation — all configurable via a simple Admin API.

Securing Quarkus Microservices via Kong API Gateway - diagram

In this tutorial, you will learn how to secure a Quarkus-based microservice using Kong API Gateway. We’ll walk through:

  • Building and containerizing a Quarkus REST API
  • Setting up Kong with Docker and configuring services/routes
  • Applying Kong plugins for authentication and rate limiting
  • Testing access control through the gateway

By the end of this guide, you’ll have a fully functioning Quarkus microservice secured via Kong, ready to handle production-level concerns like access control and traffic management.


Prerequisites

Before diving into securing Quarkus microservices with Kong, make sure you have the following tools and knowledge ready:

Technical Requirements

  • Java 17 or later installed
  • Apache Maven (for building the Quarkus project)
  • Docker and Docker Compose are installed and running
  • An HTTP client tool, such as HTTPie or curl, for testing Kong's Admin API
  • A modern code editor or IDE (e.g., VS Code, IntelliJ IDEA)

Basic Knowledge

  • Familiarity with Java and basic RESTful APIs
  • Understanding of Quarkus or similar Java frameworks
  • Basic experience with Docker
  • General understanding of what an API Gateway does

You don’t need to be a Kong expert — we’ll walk through each configuration step-by-step using Kong’s Admin API and Dockerized setup.


1. Setting Up the Quarkus Microservice

To begin, we’ll create a simple Quarkus REST API that will later be secured via Kong. This service will expose a sample endpoint that returns a basic message.

1.1 Generate a Quarkus Project

You can generate a new Quarkus project using the Quarkus Starter or via the CLI. For this tutorial, we’ll use Maven:

mvn io.quarkus:quarkus-maven-plugin:3.22.3:create \
    -DprojectGroupId=com.djamware \
    -DprojectArtifactId=secure-quarkus-service \
    -DclassName="com.djamware.api.SecureResource" \
    -Dpath="/api/secure" \
    -Dextensions="resteasy-reactive"

This command creates a new Quarkus project with a REST endpoint using the RESTEasy Reactive extension.

1.2 Explore the Project Structure

After generating the project, you’ll have the following structure:

secure-quarkus-service/
├── src/
│   └── main/
│       └── java/com/djamware/api/SecureResource.java
├── pom.xml

The SecureResource.java class will look like this by default:

package com.djamware.api;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/api/secure")
public class SecureResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello from Quarkus REST";
    }
}

1.3 Run the Quarkus Application

To run the application in development mode:

cd secure-quarkus-service
mvn quarkus:dev

Visit http://localhost:8080/api/secure in your browser or run:

curl http://localhost:8080/api/secure

You should see:

Securing Quarkus Microservices via Kong API Gateway - hello quarkus

Once the microservice is working, we’re ready to Dockerize it for deployment with Kong.


2. Dockerizing the Quarkus Microservice

To deploy our Quarkus microservice alongside Kong using Docker Compose, we need to containerize it. Quarkus makes this straightforward with its native support for container builds. We don't need to add a Dockerfile because it is generated while creating a Quarkus application.

2.1 Build the Docker Image

Make sure Docker is running, then build the image:

docker build -f src/main/docker/Dockerfile.jvm -t secure-quarkus-service .

2.2 Run the Container

You can test the Docker container locally:

docker run -i --rm -p 8080:8080 secure-quarkus-service

Access it again via:

curl http://localhost:8080/api/secure

You should see:

Hello from Quarkus REST

Now that the microservice is containerized and running, we're ready to configure Kong API Gateway and expose this service securely.


3. Setting Up Kong API Gateway with Docker

We’ll run Kong along with its required PostgreSQL database using Docker Compose. Kong will act as a reverse proxy in front of your Quarkus microservice.

3.1 Create docker-compose.yml File

In your project root (or a separate folder), create a file named docker-compose.yml with the following content:

version: '3.8'

services:
  kong-database:
    image: postgres:13
    container_name: kong-db
    environment:
      POSTGRES_USER: kong
      POSTGRES_DB: kong
      POSTGRES_PASSWORD: kong
    ports:
      - "5432:5432"
    volumes:
      - kong-db-data:/var/lib/postgresql/data

  kong-migrations:
    image: kong:3.6
    command: kong migrations bootstrap
    depends_on:
      - kong-database
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kong
      KONG_PASSWORD: kong

  kong:
    image: kong:3.6
    container_name: kong
    restart: always
    depends_on:
      - kong-database
    ports:
      - "8000:8000"       # Kong proxy
      - "8443:8443"       # Kong proxy (SSL)
      - "8001:8001"       # Kong Admin API
      - "8444:8444"       # Kong Admin API (SSL)
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kong
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444

volumes:
  kong-db-data:

3.2 Start Kong and PostgreSQL

Run the following command in the same directory as your docker-compose.yml file:

docker-compose up -d

This will:

  • Launch a PostgreSQL container
  • Run Kong's initial database migrations
  • Start the Kong Gateway

3.3 Verify Kong Is Running

Once started, verify Kong is working by accessing its Admin API:

curl http://localhost:8001/

You should see JSON output with version info like:

{"hostname":"127f9be14d79","edition":"community",...}

Kong is now ready to act as your microservices gateway.


4. Registering the Quarkus Microservice with Kong

Kong uses Services and Routes to manage upstream APIs. A Service represents your Quarkus API, and a Route defines how Kong exposes it.

Let’s register your Quarkus microservice running at http://host.docker.internal:8080 (on macOS/Windows) or http://<your-local-IP>:8080 (on Linux).

4.1 Create a Service

Run this command to register the Quarkus API as a service in Kong:

curl -i -X POST http://localhost:8001/services \
  --data name=quarkus-service \
  --data url=http://host.docker.internal:8080

🔍 host.docker.internal allows containers to reach services on your host machine (works on macOS & Windows).

You should get a 201 Created response with the service JSON.

4.2 Add a Route to the Service

Now define a route to expose that service:

curl -i -X POST http://localhost:8001/services/quarkus-service/routes \
  --data name=quarkus-route \
  --data 'paths[]=/quarkus-api'

This means that when you send a request to http://localhost:8000/quarkus-api, Kong will proxy it to your Quarkus service.

4.3 Test the Proxy Route

Now, try accessing your API through Kong:

curl http://localhost:8000/quarkus-api/api/secure

You should get:

Hello from Quarkus REST

🎉 Kong is now routing traffic to your Quarkus microservice!


5. Securing the API with Key Authentication

Kong’s Key Authentication plugin protects your routes by requiring a valid API key in the request. Here’s how to enable and use it:

5.1 Enable the Key Auth Plugin on the Route

Use this command to enable the plugin on your quarkus-route:

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

This tells Kong to require a valid API key (via header apikey) on any request to /quarkus-api.

5.2 Create a Consumer

A consumer represents a user or client accessing your API. Let’s create one:

curl -i -X POST http://localhost:8001/consumers \
  --data username=quarkus-client

5.3 Generate an API Key for the Consumer

curl -i -X POST http://localhost:8001/consumers/quarkus-client/key-auth

You’ll receive a JSON response like:

{"ttl":null,"created_at":1748050207,"id":"11df8505-b06d-417c-8c6f-7a08291f7fe0","key":"zxV79sBcOAmRdWdmZhbF1J9VJ4Pw0Gnd","tags":null,"consumer":{"id":"071fb13d-49db-4440-ab09-2628a74b09bb"}}

📝 Copy the key value — you'll use it in API requests.

5.4 Test the Secured Endpoint

Try accessing your endpoint without an API key:

curl http://localhost:8000/quarkus-api/api/secure

You’ll get a 401 Unauthorized:

{
  "message":"No API key found in request",
  "request_id":"eb09961896e4923aed8a445365763b2a"
}

Now try again with the API key:

curl --header "apikey: zxV79sBcOAmRdWdmZhbF1J9VJ4Pw0Gnd" \
  http://localhost:8000/quarkus-api/api/secure

You should see the expected response:

Hello from Quarkus REST

✅ You’ve now successfully secured your Quarkus microservice using Kong’s API gateway with key authentication.


6. Optional: Adding a Developer Portal or Rate Limiting

6.1 Enabling Rate Limiting

Rate limiting helps prevent abuse and ensures fair usage of your API. Kong provides a plugin called rate-limiting.

Let’s enable it for the quarkus-route:

curl -i -X POST http://localhost:8001/routes/quarkus-route/plugins \
  --data name=rate-limiting \
  --data config.minute=5 \
  --data config.policy=local

This configuration:

  • Allows 5 requests per minute
  • Uses the local policy (rate limits are stored in Kong’s memory)

You can also use the redis policy for distributed rate limiting in clustered environments.

Try hitting the endpoint more than 5 times in a minute:

for i in {1..6}; do 
  curl --header "apikey: zxV79sBcOAmRdWdmZhbF1J9VJ4Pw0Gnd" http://localhost:8000/quarkus-api/api/secure && echo
done

The 6th request should return:

{
  "message":"API rate limit exceeded",
  "request_id":"7a94a854bb4bb57be349e06e5c8cf76d"
}

6.2 Developer Portal (Enterprise Only)

Kong provides a Developer Portal for teams using Kong Enterprise. It allows you to:

  • Expose your APIs
  • Share documentation (like Swagger/OpenAPI)
  • Let developers self-register and obtain API keys

If you're using the OSS version of Kong (which we are in this tutorial), the Developer Portal is not included.

However, you can integrate external tools like:

  • Swagger UI
  • Redoc
  • Static docs sites (e.g., Docusaurus)

You could also create a lightweight developer portal yourself using:

  • A frontend (React, Vue, etc.)
  • Kong Admin API for key management
  • Documentation pages with usage examples

🔐 Summary of Enhancements

Feature Plugin/API  Purpose
Authentication `key-auth` Restrict access via API keys
Rate Limiting  `rate-limiting` Prevent abuse and throttle usage
Developer Access Kong Admin API Manage consumers and credentials
API Documentation Swagger, Redoc Help devs understand your endpoints


7. Managing API Keys Programmatically via Kong Admin API

Kong provides a RESTful Admin API that lets you manage Consumers and their API keys. You can use it from any backend system (e.g., Node.js, Python, Go) or CLI tools like curl.

7.1 Create a New Consumer (User or Client)

curl -i -X POST http://localhost:8001/consumers \
  --data username=new-user

Optional: add custom metadata (e.g., email, tags):

curl -i -X POST http://localhost:8001/consumers \
  --data username=new-user \
  --data custom_id=12345 \
  --data tags=client \
  --data tags=free-tier

7.2 Generate an API Key for the Consumer

curl -i -X POST http://localhost:8001/consumers/new-user/key-auth

Response:

{"ttl":null,"created_at":1748050917,"id":"82235ec8-d311-4a4d-8a7f-7f081af3a758","key":"FeEeu1TIou0ak9b6ujGGmPVT3Rfw7gfP","tags":null,"consumer":{"id":"0ee0a5d4-0a09-4011-b193-14fbec8a73f7"}}

🔐 You can now send this key to the user via email or the dashboard.

7.3 List All Keys for a Consumer

curl http://localhost:8001/consumers/new-user/key-auth

7.4 Revoke (Delete) an API Key

Use the key ID or key value to delete:

curl -i -X DELETE http://localhost:8001/consumers/new-user/key-auth/{key_or_id}

Example:

curl -i -X DELETE http://localhost:8001/consumers/new-user/key-auth/a9f8n3jdg934hf3n

7.5 Rotate an API Key

There’s no direct "rotate" action. Just delete the old key and create a new one:

# Step 1: Delete old key
curl -i -X DELETE http://localhost:8001/consumers/new-user/key-auth/old-key

# Step 2: Create new key
curl -i -X POST http://localhost:8001/consumers/new-user/key-auth

🛠️ Pro Tip: Automate This in Code

Use your backend to expose a /register or /get-key endpoint that interacts with Kong’s Admin API, like:

// Node.js Example using Axios
const axios = require('axios');

async function createConsumer(username) {
  await axios.post('http://localhost:8001/consumers', { username });
  const res = await axios.post(`http://localhost:8001/consumers/${username}/key-auth`);
  return res.data.key;
}

You could then show this key in a user dashboard or send it via email.


Conclusion

In this tutorial, you learned how to secure Quarkus microservices using Kong API Gateway. Starting from Dockerizing a Quarkus app, you deployed Kong with Docker, registered your microservice, and enforced key-based authentication using Kong’s powerful plugin system. You also added rate limiting to throttle traffic and explored how to manage API keys programmatically via Kong’s Admin API.

These practices not only secure your microservices but also help you scale API access and simplify developer onboarding. With Kong’s flexibility and Quarkus’s performance, you now have a production-ready foundation for secure microservices in the cloud or on-prem.

You can find the full source code on our GitHub.

That just the basic. If you need more deep learning about Java and Spring Framework you can take the following cheap course:

Thanks!