Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Authorizing multi-language microservices with Louketo Proxy

August 3, 2020
Rarm Nagalingam
Related topics:
SecurityDevOpsMicroservicesLinux

Share:

    Update August 25, 2020: The Louketo Proxy team has announced that it is sunsetting the Louketo project. Read the link for more information, and watch our site for a new article detailing how to authorize multi-language microservices using a different method.

    What if you needed to provide authentication to several microservices that were written in different languages? You could use Red Hat Single Sign-On (SSO) to handle the authentication, but then you would still need to integrate each microservice with Keycloak. Wouldn't it be great if a service could just handle the authentication flow and pass the user's details directly to your microservices? In this article, I introduce a service that does just that!

    Louketo Proxy

    Louketo Proxy (previously Keycloak-Gatekeeper) integrates with OpenID Connect (OIDC)-compliant providers like Keycloak. Louketo Proxy hands off the authentication to Keycloak, and then passes the authorization and user details to a microservice as header attributes. The diagram in Figure 1 illustrates the authentication flow between Louketo Proxy, Keycloak, and a microservice.

    A diagram of Louketo Proxy's authentication flow.
    Figure 1: Louketo Proxy authenticates a microservice with Keycloak.

    With Louketo Proxy, you don't need to worry about supporting the authentication flow across the different languages used for your microservices. As an added benefit, Louketo Proxy makes it easy to provide authentication to legacy off-the-shelf applications that do not support OIDC.

    Louketo Proxy in OpenShift

    Before getting started, it is worthwhile to explore the architecture that is required to run Louketo Proxy and a microservice together. In a Red Hat OpenShift deployment, the usual pattern is for a single pod to run a single container, as shown in Figure 2.

    A diagram of an OpenShift deployment where one pod runs one container.
    Figure 2: A typical OpenShift deployment where one pod runs one container.

    For our Louketo Proxy pattern to work, we need one pod to run two containers. Louketo Proxy and the microservice will reside within the same pod and share the resources associated with that pod, including networking. To prevent conflict, Louketo Proxy and the microservice will need to listen on different network ports. The Louketo Proxy instance also must be able to communicate with the microservice without traversing any network links. This setup reduces latency and makes it difficult to execute a man-in-the-middle (MITM) attack, which improves the security model. Figure 3 shows the OpenShift deployment pattern for Louketo Proxy with microservices.

    Authorizing multi-language microservices with Louketo Proxy
    Figure 3: The Louketo Proxy instance and microservice run in the same pod and share the pod's resources.

    Normally, we would create a service bound to the microservice and expose it via a route. In this case, we only create a service bound to the Louketo Proxy instance and expose it via a route. Consumers will only ever access the microservice via the Louketo Proxy instance. This arrangement enforces the security model.

    Getting started with Louketo Proxy

    For this example, we deploy a simple Flask application that exposes the authentication headers passed along by Louketo Proxy. If you wish, you can run the example code on Red Hat CodeReady Containers (CRC). Otherwise, you will need to update the code to run on your OpenShift cluster.

    Step 1: Deploy Keycloak

    The first step is to deploy Keycloak on CodeReady Containers. To fast-track the process, run the following commands from a terminal. These will create a project on OpenShift, deploy Keycloak, and create a route:

    $ oc new-project sso-test
    $ oc new-app --name sso --docker-image=quay.io/keycloak/keycloak -e KEYCLOAK_USER='admin' -e KEYCLOAK_PASSWORD='louketo-demo' -e PROXY_ADDRESS_FORWARDING='true’
    $ oc create route edge --service=sso --hostname=sso.apps-crc.testing
    

    Create and configure the Flask client

    Browse to https://sso.apps-crc.testing and log in with the username admin and the password louketo-demo. Once there, select Clients from the left-hand menu and create a new client with the fields shown in Figure 4.

    A screenshot of the Add Client dialog.
    Figure 4: Add a new Flask client.

    After you have created the client, you will have the option to switch the client access type from public to confidential, as shown in Figure 5.

    A screenshot of the Settings dialog in the Flask UI.
    Figure 5: Use the Settings dialog to switch client access to confidential.

    CodeReady Containers will generate a client secret, which you can view under the Credentials tab shown in Figure 6. You will need the secret when we configure Louketo Proxy, so make a note of it.

    A screenshot of the Credentials dialog in the Flask UI.
    Figure 6: Check under the Credentials tab to see the generated client secret.

    Configure the mappers

    At this point, we are still configuring the Flask client. Select the Mappers tab and add two mappers:

    • Groups:
      • Name: groups
      • Mapper type: Group Membership
      • Token claim name: groups
    • Audience:
      • Name: audience
      • Mapper type: Audience
      • Included client audience: flask

    Figure 7 shows the configuration for the Audience mapper.

    A screenshot of the dialog to create the Audience mapper.
    Figure 7: Configure the Flask client's Audience mapper.

    Figure 8 shows the configuration for the Groups mapper.

    A screenshot of the dialog to create the Groups mapper.
    Figure 8: Configure the Flask client's group-membership mapper.

    Configure the user groups

    Now select Groups from the left-hand menu and add two groups:

    • admin
    • basic_user

    Configure the user

    Again from the left-hand menu, select Users and add a user. Be sure to enter an email and set a password for the user, then add the user to the basic_user and admin groups that you just created. Next, we'll configure Louketo Proxy and the example application.

    Step 2: Configure Louketo Proxy and the application

    We will need the following details from our Keycloak server (note that you will enter the client secret that you saved in Step 1):

    • Client ID: flask
    • Client secret
    • Discovery URL: https://sso.apps-crc.testing/auth/realms/master
    • Groups: basic_user

    Create the ConfigMaps

    First, we'll use a ConfigMap to configure Louketo Proxy. Louketo Proxy supports presenting custom pages (sign-in pages, forbidden pages, and so on) that can match the look-and-feel of the associated microservice. For our use case, we will redirect all unauthenticated requests to Keycloak. Make sure that you replace the client-secret in the following ConfigMap with the one generated by Keycloak:

    apiVersion: v1
    kind: ConfigMap
    metadata:
     name: gatekeeper-config
    data:
     keycloak-gatekeeper.conf: |+
       # The URL for retrieving the OpenID configuration - normally the /auth/realms/
       discovery-url: https://sso.apps-crc.testing/auth/realms/master
       # skip tls verify
       skip-openid-provider-tls-verify: true
       # the client ID for the 'client' application
       client-id: flask
       # the secret associated with the 'client' application
       client-secret: < Paste Client Secret here >
       # the interface definition you wish the proxy to listen to, all interfaces are specified as ':', unix sockets as unix://|
       listen: :3000
       # whether to enable refresh-tokens
       enable-refresh-tokens: true
       # the location of a certificate you wish the proxy to use for TLS support
       tls-cert:
       # the location of a private key for TLS
       tls-private-key:
       # the redirection URL, essentially the site url, note: /oauth/callback is added at the end
       redirection-url: https://flask.apps-crc.testing
       secure-cookie: false
       # the encryption key used to encode the session state
       encryption-key: nkOfcT6jYCsXFuV5YRkt3OvY9dy1c0ck
       # the upstream endpoint which we should proxy request
       upstream-url: http://127.0.0.1:8080/
       resources:
       - uri: /*
         groups:
         - basic_user
    

    Next, we'll create a ConfigMap for the Flask application. Before we can create the ConfigMap, we need to obtain the public key for Keycloak. To get the public key, log in to the Keycloak admin page and go to Realm Settings > Keys. From there, select the RS256 public key, as shown in Figure 9.

    A screenshot of the option to select the RSA-generated public key.
    Figure 9: Select the RSA-generated public key.

    The Flask application uses this public key to check the validity of the JSON Web Token (JWT) that Louketo Proxy passes. Here is the ConfigMap for the Flask application:

    kind: ConfigMap
    apiVersion: v1
    metadata:
     name: sso-public-key
    data:
     PUBLIC_KEY: |
       -----BEGIN PUBLIC KEY-----
       < Paste in the Keycloak public key here >
       -----END PUBLIC KEY-----
    

    Bind the service

    Now we need to bind a service to the Louketo Proxy listening port. We defined the listening port in Louketo Proxy's ConfigMap under the listen parameter. Here is the service binding:

    apiVersion: v1
    kind: Service
    metadata:
     name: flask
    spec:
     ports:
     - port: 3000
       protocol: TCP
       targetPort: 3000
     selector:
       app: flask
    

    Configure the route

    We use routes to expose our services to consumers. In this case, we are exposing the Louketo Proxy service and the terminating TLS on the router:

    kind: Route
    apiVersion: route.openshift.io/v1
    metadata:
     name: flask
    spec:
     host: flask.apps-crc.testing
     to:
       kind: Service
       name: flask
       weight: 100
     port:
       targetPort: 3000
     tls:
       termination: edge
       insecureEdgeTerminationPolicy: Redirect
     wildcardPolicy: None
    

    Apply the DeploymentConfig

    Now that we have created the ConfigMaps, service, and route we can apply our OpenShift DeploymentConfig. If you look carefully at the configuration below, you will see that we are deploying two containers within the same DeploymentConfig. As I said at the beginning of this article, our architecture calls for deploying two containers within the same pod:

    kind: DeploymentConfig
    apiVersion: apps.openshift.io/v1
    metadata:
     name: flask
     labels:
       app: flask
    spec:
     strategy:
       type: Rolling
     replicas: 1
     selector:
       app: flask
     template:
       metadata:
         labels:
           app: flask
       spec:
         containers:
           - name: flask
             image: quay.io/rarm_sa/flask-sso-gatekeeper
             ports:
               - containerPort: 8080
                 protocol: TCP
             envFrom:
               - configMapRef:
                   name: sso-public-key
             imagePullPolicy: IfNotPresent
           - name: gatekeeper
             image: 'quay.io/louketo/louketo-proxy'
             args:
               - --config=/etc/keycloak-gatekeeper.conf
             ports:
               - containerPort: 3000
                 name: gatekeeper
             volumeMounts:
               - name: gatekeeper-config
                 mountPath: /etc/keycloak-gatekeeper.conf
                 subPath: keycloak-gatekeeper.conf
         volumes:
           - name : gatekeeper-config
             configMap:
               name: gatekeeper-config
    

    Test the configuration

    To test your configuration, browse to the example application at https://flask.apps-crc.testing. You will be redirected to Keycloak and presented with a login screen like the one in Figure 10. Enter the username and password for your application user.

    A screenshot of the Keycloak login screen.
    Figure 10: The Keycloak login screen.

    Once you have authenticated the user, you will be redirected to an application page that returns a JSON file. The file exposes the headers passed along by Louketo Proxy, as shown in Figure 11.

    A screenshot of the JSON file.
    Figure 11: The Flask application returns a JSON file that exposes the Louketo Proxy headers.

    Conclusion

    This article introduced you to Louketo Proxy, a simple way to provide authentication for your applications without having to code your own OpenID Connect clients within your microservices. As always, I welcome your questions and feedback in the comments.

    Last updated: August 25, 2020

    Recent Posts

    • A deep dive into Apache Kafka's KRaft protocol

    • Staying ahead of artificial intelligence threats

    • Strengthen privacy and security with encrypted DNS in RHEL

    • How to enable Ansible Lightspeed intelligent assistant

    • Why some agentic AI developers are moving code from Python to Rust

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue