DEV Community

Robin Cher
Robin Cher

Posted on

Securing your site via OIDC, powered by Kong and KeyCloak

Quick sharing on how you can further secure your api or endpoints with OIDC, and powered by Kong and Keycloak. The examples shared are all open-source solutions.


As we start shipping services out to the open world, one of the primary considerations is how we can prevent any malicious attacks, since now we are in the wild west.Thankfully, We have the opportunity to tinker and experiment with open-source solutions due our work nature at that time. In this post, i would like to share how we incorporate Kong Ingress Controller, KeyCloak and Kubernetes to have an initial OIDC flow to front our external services.

System Context

Before we dive deeper, let's take a closer look on how OIDC will verify the authenticity of a user before allowing the request to be fulfilled.

OIDC (OpenID Connect) Overview

Extracted from :

Image description


Before we begin, we need to have the following :

  • Kong - An API Gateway (community edition is open source and free)
  • Kong OIDC Plugin - Open-sources OIDC plugin for Kong, maintained by the community
  • Kong JWT KeyCloak Plugin - Plugin for Kong so as to allow JWT token to be issued and validated by Keycloak. Maintained by the community
  • Keycloak - A OpenID Connect Provider (Open Source)
  • Kubernetes - Open-source container orchestration system where we will deploy Kong and KeyCloak

Baking the OIDC Plugin with Kong Base Image

Important Note : This is a community maintained OIDC Plugin. If required, please consider checking out the official OIDC Plugin that is only available with Kong Enterprise

As we are using the open-source plugin by Revomatico, we need to bake the plugin with the base kong image.

Sample Dockerfile

FROM kong/kong:2.7.0


USER root
RUN apk update && apk add git=${GIT_VERSION} unzip=${UNZIP_VERSION} luarocks=${LUAROCKS_VERSION}
RUN luarocks install kong-oidc

RUN git clone --branch v1.2.3-2
WORKDIR /kong-oidc
RUN luarocks make

RUN luarocks pack kong-oidc ${OIDC_PLUGIN_VERSION} \
     && luarocks install kong-oidc-${OIDC_PLUGIN_VERSION}.all.rock

RUN git clone --branch 20200505-access-token-processing
WORKDIR /kong-plugin-jwt-keycloak
RUN luarocks make

RUN luarocks pack kong-plugin-jwt-keycloak ${JWT_PLUGIN_VERSION} \
     && luarocks install kong-plugin-jwt-keycloak-${JWT_PLUGIN_VERSION}.all.rock

USER kong
Enter fullscreen mode Exit fullscreen mode

Build and push the image to a registry

# Build the container with any new changes
docker build -t <reponame>/kong-oidc:<tag> -f Dockerfile . 

# Run the container in detached mode
docker run -d --name kong-oidc <reponame>/kong-oidc:<tag>       

# Pushing the container image to a registry
docker push <reponame>/kong-oidc:<tag>   
Enter fullscreen mode Exit fullscreen mode

Understand the Kong Cluster Plugin Configurations

Kong Ingress Controller allow us to configure Kong specific features using several Custom Resource Definitions(CRDs)

These are the following CRDs that we need to take note of

  1. odic - This plugin is used to communicate with the Keycloak Identity provider and is required if you'd like to enable (recommended) SSO for your ingress.

  2. request-transformer - To strip off unnecessary headers upon authentication with the identity platform

  3. cors - Allow Cross Site origin at global level

Deploying into Kubernetes

Examples manifest can be found on here

  1. #### Deploy the previously baked Kong image (with OIDC plugin).
kubectl apply -f kong-deployment.yaml
Enter fullscreen mode Exit fullscreen mode
  1. #### Deploy KeyCloak
kubectl apply -f keycloak-deployment.yaml
Enter fullscreen mode Exit fullscreen mode


KeyCloak Configurations

  • Create a new Realm in KeyCloak

Image description

  • Create a new Kong Client in the realm , eg kong-oidc

Image description

  • Client Configurations

Go to Clients, and then click on Settings.

Make the following updates

Access Type: Confidential
Valid Redirect URIs: *
Web Origin: localhost (Allowed CORS origin)

  • Copied the Client ID, and then go to Credentials to get the Secret value.

Image description

  • Retrieve OpenID Endpoint Configuration

Go to Realm Setting, and select General. Click on OpenID Endpoint Configuration

Image description

  • Override the values of the OIDC Kong Plugins
kind: KongClusterPlugin
  name: oidc
  annotations: "kong"
    global: "false"
disabled: false # optionally disable the plugin in Kong
plugin: oidc
config: # configuration for the plugin
  client_id: kong-oidc # Realm
  client_secret: xxxxxxxx  # Client Secret Copied
  realm: kong
  discovery: https://localhost/.well-known/openid-configuration # OpenID Endpoint Configuration Copied
  scope: openid
  redirect_after_logout_uri : https://localhost/auth/realms/kong/protocol/openid-connect/logout?redirect_uri=https://localhost
Enter fullscreen mode Exit fullscreen mode


Deploy the required Cluster Plugins as mentioned above

kubectl apply -f kong-crds.yaml
Enter fullscreen mode Exit fullscreen mode


Testing your site with OIDC

We can now test a sample ingress that is intercepted by Kong Ingress Controller. All you have to do is indicating the plugins annotations on the ingress

# sample-oidc.yaml
kind: Ingress
  name: echoserver-oidc
  namespace: default
  annotations: request-transformer,oidc #indicate here
  ingressClassName: kong
    - host:
          - path: /
            pathType: Prefix
                name: echoserver
                  number: 80
Enter fullscreen mode Exit fullscreen mode

You should be prompted to sign in when attempting to access the site, and have successfully implement a minimal OIDC solution using open-source technology !


  • We choose Kong because of its flexibility (we only scratch its surface on what it capable of as a full-fledge API Gateway) and being lightweight, which allow us to make changes quickly. Additionally, it is cloud-native which ease the effort of deployment.

  • KeyCloak is the de-facto IAM solution we have in our lab, and integrating it is straight forward enough. We don't really have to re-engineer much in the near future when we onboard more type of user pools (Social Logins, Azure Active Directory etc..)

  • If possible, start something small to see if it work as intended, especially when there are many inter-connected dots. It is always good to retain some technical acumen internally to allow better decision making when engaging with our software partners.


This work is not possible without the contribution from my following team mates:

Wee Liang - DevOps Engineer @ Thales Airlab
Arun - DevOps & Integration @ Thales Airlab
Kelvin - Software Engineer @ Thales Airlab


Discussion (0)