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.

Introduction

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 : https://github.com/nokia/kong-oidc

Image description

Preparation

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

ENV OIDC_PLUGIN_VERSION=1.2.3-2
ENV JWT_PLUGIN_VERSION=1.1.0-1
ENV GIT_VERSION=2.24.4-r0
ENV UNZIP_VERSION=6.0-r7
ENV LUAROCKS_VERSION=2.4.4-r1


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 https://github.com/revomatico/kong-oidc.git
WORKDIR /kong-oidc
RUN luarocks make

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

WORKDIR /
RUN git clone --branch 20200505-access-token-processing https://github.com/BGaunitz/kong-plugin-jwt-keycloak.git
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

3.

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


apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
  name: oidc
  annotations:
    kubernetes.io/ingress.class: "kong"
  labels:
    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

4.

Deploy the required Cluster Plugins as mentioned above



kubectl apply -f kong-crds.yaml


Enter fullscreen mode Exit fullscreen mode

5

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
....
....
----
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echoserver-oidc
  namespace: default
  annotations:
    konghq.com/plugins: request-transformer,oidc #indicate here
spec:
  ingressClassName: kong
  rules:
    - host: echo-oidc.localhost.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service: 
                name: echoserver
                port: 
                  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 !

Learnings

  • 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.

Credits

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

References

Top comments (11)

Collapse
 
rajeeshcs profile image
rajeesh-cs • Edited

Hi Robin,

I have followed the docs and installed Kong with customised OIDC plugin.

However, when the kong-crds.yaml is getting deployed it shows the CRD error.

resource mapping not found for name: "oidc" namespace: "" from "kubernetes/kong-crds.yaml": no matches for kind "KongClusterPlugin" in version "configuration.konghq.com/v1"
ensure CRDs are installed first
resource mapping not found for name: "cors" namespace: "" from "kubernetes/kong-crds.yaml": no matches for kind "KongClusterPlugin" in version "configuration.konghq.com/v1"
ensure CRDs are installed first
resource mapping not found for name: "request-transformer" namespace: "" from "kubernetes/kong-crds.yaml": no matches for kind "KongClusterPlugin" in version "configuration.konghq.com/v1"
ensure CRDs are installed first
Enter fullscreen mode Exit fullscreen mode

Does the custom Kong install Ingress Controller as well?

I have followed the instructions as in the document. Is the CRD requires Ingress component? Or the Dockerfile provides only core Gateway?

Collapse
 
robincher profile image
Robin Cher

Did you include the required custom plugins ?

export KONG_PLUGINS=bundled,oidc

There are some updates to Kong KIC API, do have a look.

Collapse
 
rajeeshcs profile image
rajeesh-cs

Correct. I have included in Helm chart and it started working. Thanks!

Thread Thread
 
robincher profile image
Robin Cher

Happy to hear that, thanks for using Kong :)

Collapse
 
bermuda_2448_8923de7edadd profile image
BERMUDA 2448 • Edited

where to include the required custom plugins? when the kong-deployment.yaml file is applied to the cluster, no 'kong' ingress-class is created. Please hlep..I followed steps mentioned above but at the end, the ingress object created but not responding to external request..

Collapse
 
rajeeshcs profile image
rajeesh-cs

Hi Robin,

This is a different topic.

Need to validate the Kong route with the Keycloak authorisation configurations.
For i.e, there is an enforce set of methods available in** keycloak-connect plugin **npmjs.com/package/keycloak-connect.... The above methods work according to the Authorisation configuration in Keycloak Client which consists of Resources, Policies, Permissions and Scopes.

Just wondering, are the similar features are available in either OIDC or any other plugins in Kong?

-Rajeesh

Collapse
 
zaryab123 profile image
Zaryab Raza Malghani • Edited

Hi Robin, hope you are fine.
I've followed your article and setup the kong-ingress with both keycloak and sample-echo-app, also doing configuration of oidc plug-in in kong-crds.yml as provided in article. When i run echo-app with kong plug-ins (specifically oidc plugin), it throughs 404-not found error while accessing the sample-app url path.

I debugged the app and removed the oidc plugin from annotations in ingress config of sample-oidc.yml and it starts working fine. So, i came to conclusion that there might be error in kong-plugin (One that we configure in kong-crds.yml). Can you please debug it for me? i'll send you all the config files that i am using so you can quick run them on your side.

Hope you are having a good day and waiting for your reply, thanks.

Collapse
 
robincher profile image
Robin Cher

Hi, as this is the custom plugin provided by the third-party, better to check with them the update changes. github.com/revomatico/kong-oidc

Collapse
 
koo9 profile image
Kevin

does this plugin support route level OIDC?

Collapse
 
ayushic2899 profile image
Ayushi choudhary

Hii Robin...I have done the same things still when I am opening the site it's not redirecting to keycloak can uh help what I am doing wrong?

Collapse
 
robincher profile image
Robin Cher

Can share with me your ingress and Kong plugin set-up ?