API security is a critical aspect of modern web and mobile application development, where APIs serve as the backbone for communication between different systems. In this context, securing these APIs is paramount. Two technologies that have emerged as leading tools for enhancing API security are Kong Gateway and Open Policy Agent (OPA). Kong Gateway provides a robust API management solution with flexible routing, load balancing, and security policies, while OPA enables fine-grained, customizable policy enforcement. Together, these tools form a comprehensive framework for securing APIs at scale.

In this article, we will explore how to enhance API security using Kong Gateway for securing APIs and OPA for handling policy decisions, complete with code examples and a thorough discussion of the concepts.

What is Kong Gateway?

Kong Gateway is an open-source, cloud-native API gateway built on NGINX that helps organizations manage, monitor, and secure their APIs. As an API gateway, it acts as a reverse proxy, intercepting incoming API requests and forwarding them to the appropriate backend services.

Key features of Kong Gateway include:

  • Rate limiting: Control the number of requests an API can handle.
  • Authentication and Authorization: Supports various forms of authentication (OAuth2, JWT, API keys, etc.).
  • Traffic control: Manages load balancing, retries, circuit breakers, and more.
  • Logging and Monitoring: Provides extensive metrics for monitoring traffic.

Basic Setup of Kong Gateway

First, let’s start by setting up Kong Gateway on a Docker environment. Here’s how you can configure a basic Kong Gateway:

bash

docker network create kong-net

# Start a PostgreSQL instance for Kong
docker run -d –name kong-database \
–network=kong-net \
-p 5432:5432 \
-e “POSTGRES_USER=kong” \
-e “POSTGRES_DB=kong” \
postgres:9.6

# Run the Kong Gateway instance
docker run -d –name kong \
–network=kong-net \
-e “KONG_DATABASE=postgres” \
-e “KONG_PG_HOST=kong-database” \
-e “KONG_CASSANDRA_CONTACT_POINTS=kong-database” \
-e “KONG_ADMIN_LISTEN=0.0.0.0:8001” \
-p 8000:8000 \
-p 8001:8001 \
kong

Now that Kong is running, you can use its Admin API (available at port 8001) to configure services and routes.

Securing APIs with Kong

Kong supports multiple security plugins, including OAuth2, JWT, and basic authentication. Here’s how to secure an API using the JWT Plugin.

Create a Service

A Service represents an upstream API that Kong manages.

bash
curl -i -X POST http://localhost:8001/services/ \
--data name=my-service \
--data url='http://httpbin.org'

Create a Route

Routes define how incoming requests map to services.

bash
curl -i -X POST http://localhost:8001/services/my-service/routes \
--data 'hosts[]=example.com'

Enable JWT Plugin

JWT authentication requires clients to send a JWT token with their requests.

bash
curl -i -X POST http://localhost:8001/services/my-service/plugins \
--data name=jwt

Add a Consumer

A Consumer represents a client using the API. Each consumer is issued credentials.

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

Add JWT Credentials for the Consumer

bash
curl -i -X POST http://localhost:8001/consumers/example-user/jwt

With these steps, we’ve enabled basic API security using JWT authentication on Kong Gateway. Now, any request made to the route requires a valid JWT token.

Introduction to Open Policy Agent (OPA)

Open Policy Agent (OPA) is a general-purpose policy engine that can be integrated into various systems to provide policy-based access control. OPA decouples policy decisions from application logic, making it easier to manage security rules across microservices and APIs.

OPA operates based on the Rego language, which allows you to write declarative policies. These policies can be used for fine-grained access control, filtering data, and enforcing various business rules.

How OPA Works

  1. Input: OPA receives an input, which is typically the request data (HTTP headers, method, path, etc.).
  2. Policy Evaluation: Based on the input, OPA evaluates the request against predefined policies written in Rego.
  3. Decision: OPA returns a decision that determines whether the request should be allowed or denied.

Example of OPA Policy

Let’s consider a basic example where OPA is used to authorize API requests based on user roles.

rego

package example.authz

default allow = false

allow {
input.user == “admin”
}

allow {
input.method == “GET”
input.path == “/public”
}

This policy defines two rules:

  • Allow access if the user is “admin.”
  • Allow access to all GET requests on the /public endpoint.

Now, let’s integrate OPA with Kong Gateway to enforce these policies.

Integrating Kong Gateway with OPA

To enhance API security, you can integrate Kong Gateway with OPA, delegating authorization decisions to OPA while leveraging Kong’s features for authentication, rate limiting, and logging.

Step-by-Step Integration of Kong and OPA

Deploy OPA

You can run OPA as a standalone service or within a Docker container. For example:

bash
docker run -d --name opa -p 8181:8181 openpolicyagent/opa:latest run --server

Create OPA Policies

You can write policies in Rego and store them within OPA. Save the following policy as authz.rego and load it into OPA:

rego

package kong.authz

default allow = false

allow {
input.method == “GET”
}

allow {
input.user == “admin”
}

Load this policy into OPA using the following command:

bash
curl -X PUT --data-binary @authz.rego localhost:8181/v1/policies/authz

Configure Kong to Use OPA

You need to write a Kong plugin that queries OPA for authorization decisions. The plugin can make an HTTP call to the OPA server with the request details.

Here’s an example Kong plugin in Lua:

lua

local http = require "resty.http"

local function authorize()
local httpc = http.new()
local res, err = httpc:request_uri(“http://localhost:8181/v1/data/kong/authz/allow”, {
method = “POST”,
body = ngx.req.get_body_data(),
headers = {
[“Content-Type”] = “application/json”,
}
})

if not res then
ngx.log(ngx.ERR, “Failed to query OPA: “, err)
return ngx.exit(500)
end

local body = cjson.decode(res.body)
if not body.result then
ngx.log(ngx.ERR, “OPA denied access”)
return ngx.exit(403)
end
end

return authorize

Deploy the Plugin on Kong

After writing the plugin, install it in your Kong instance and configure it for your API service.

bash
curl -i -X POST http://localhost:8001/services/my-service/plugins \
--data name=opa-authz

This plugin will query OPA to decide whether or not to allow a request based on the predefined policies.

Testing the Integration

You can now test the integration by sending requests to the API via Kong. For example, sending a GET request as an admin user should be allowed:

bash
curl -H "Authorization: Bearer <admin_token>" http://localhost:8000/my-service

A POST request from a non-admin user will be denied based on the OPA policy.

bash
curl -X POST http://localhost:8000/my-service

Conclusion

In this article, we have explored how to enhance API security by combining Kong Gateway with Open Policy Agent (OPA). Kong Gateway provides robust features for managing API traffic, authentication, and rate limiting, while OPA offers a flexible and powerful way to implement fine-grained, dynamic access control policies.

By integrating these two tools, you can ensure that your APIs are protected not just at the network level, but also at the authorization level, providing more control over who can access your services. This approach allows you to adapt to evolving security requirements and ensure that policies are consistently enforced across all APIs.

The combination of Kong Gateway for API management and OPA for policy decisions enables organizations to build scalable, secure, and compliant API-driven architectures, addressing the complexities of modern distributed systems. This solution not only enhances security but also improves maintainability by decoupling policy logic from the application code.