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
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
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>
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
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.
request-transformer - To strip off unnecessary headers upon authentication with the identity platform
cors - Allow Cross Site origin at global level
Deploying into Kubernetes
Examples manifest can be found on here
- #### Deploy the previously baked Kong image (with OIDC plugin).
kubectl apply -f kong-deployment.yaml
- #### Deploy KeyCloak
kubectl apply -f keycloak-deployment.yaml
3.
KeyCloak Configurations
- Create a new Realm in KeyCloak
- Create a new Kong Client in the realm , eg kong-oidc
- 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.
- Retrieve OpenID Endpoint Configuration
Go to Realm Setting, and select General. Click on OpenID Endpoint Configuration
- 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
4.
Deploy the required Cluster Plugins as mentioned above
kubectl apply -f kong-crds.yaml
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
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
Top comments (11)
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.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?
Did you include the required custom plugins ?
export KONG_PLUGINS=bundled,oidc
There are some updates to Kong KIC API, do have a look.
Correct. I have included in Helm chart and it started working. Thanks!
Happy to hear that, thanks for using Kong :)
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..
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
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.
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
does this plugin support route level OIDC?
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?
Can share with me your ingress and Kong plugin set-up ?