Authentication: shifting from legacy to an “off the shelf” opensource Keycloak-based product

Clément Cureau
Peaksys Engineering
5 min readJan 31, 2022

Authentication has evolved considerably over the last few years, from handling clear passwords to OAuth2 PKCE flow, and it is now becoming mandatory to adopt proven solutions to handle such sensitive subjects. Can opensource provide an answer?

Authentication in the good old days

French ecommerce leader Cdiscount was born in 1998, making it a pioneer on the age scale of the internet. Its authentication system has evolved several times, to accommodate UX and security for instance, but has ended up looking like a multi-layer legacy system! The reason for this is that authentication used to be seen as a one-time thing when bootstrapping a service — as opposed to a feature to be maintained. Until recently, it was taken for granted and considered aging-proof, so therefore not a priority to be focused on.

It is also a complex topic that is constantly evolving (who’s ever read the whole RFC?). A few years ago, there were not as many exploits out there, so it was not an area seen as justifying a dedicated product team.

We took the opportunity to do a rebuild when we were asked to offer new features to our end users (passwordless and social connect). So two years ago, we set-up a dedicated team for authN & authZ, with a workforce of 9 devops.

Where to start? For quite a few years now, Cdiscount has switched to opensource for other key components in the company, such as Kubernetes for container management, RabbitMQ & Kafka for streaming, .net/OpenJDK for microservices, PostgreSQL/MongoDB for databases. So, when it came to rebuilding our authentication system, the team went out there and evaluated a few large-scale solutions offered by the opensource world.

Candidate evaluation

We were looking for solutions capable of:

· Handling authentication and authorization for both technical components and humans

· Compatibility with the latest standards

· Resilience and high availability

· Combining external identity sources (OIDC, Active Directory, GAFAs)

I won’t be listing the pros and cons for each candidate, as there are already lots of articles available on the subject. I’ll skip straight to the conclusion now, and it’s in the title: Keycloak. It ticks all the boxes we listed. On top of that, it’s a product that’s been around for a few years now and benefits from a large and active community.

Let’s model!

Once the technical requirements had been met, we then faced the functional choices: how to model access control for each technical component in our system. We came up with the following principles:

· Each technical component owns an identity in the Keycloak “registry”, aka clientid

· Authentication is made following an OAuth2 client_credentials flow

· Access tokens are cached and sent as an Authorization HTTP header for each interaction with other components

· Realm perimeter is defined by its accessibility, i.e. internal vs. external

· API producers define exposed roles, as: {API_ROUTE}_{HTTP-VERB}

Let’s run through a real-world scenario — a picture is worth a thousand words. Say there’s a marketplace seller who wants to add products to its catalogue. First, we need to register its component identity and assign roles, which are mapped to some APIs exposed by our APIM. It can now use its technical identity to access our marketplace APIs:

1. Seller SUPERDISCOUNT authenticates to Keycloak’s /token endpoint, with a clientid & secret, on an external realm

2. It attaches the access token received from Keycloak to the request targeting the marketplace APIM, and is granted access to 3 routes:

3. The APIM handles the request and therefore authenticates to Keycloak’s /token endpoint with its own identity, with a clientid & secret, on an internal realm

4. The APIM attaches its access token received from Keycloak to the request targeting the internal API, is also granted access to 3 routes, and sends the result back to the Seller SUPERDISCOUNT

The separation between internal and external realms allows us to exercise strict control of access to APIs that are exposed on the Internet or not. It implies cross-realm communication, permitted by issuers whitelisting in a dedicated OAuth2 wrapper-library.

Access control can be configured in different ways in Keycloak. Roles are one way, and can be positioned at realm or at each component level. Also, one nice feature-preview we’ve been exploring is fine-grain admin, a very flexible way of fine-controlling identity management.

Tailoring to our needs: Github contributions welcome!

Opensource software comes with a community. It’s a two-way process and means that we get lots of new features at each release, as well as critical fixes. It’s also a good way to share use cases and contribute back some missing features. Keycloak is written in Java, a coding skill that is largely used by our developer community. We’ve had the chance to submit a few Pull Requests around fine-grained user management. A cheaper price to pay than for home-made solutions. And we made some custom developments for authentication delegation in a precise use case.

Keycloak has been built with an SPI architecture, allowing extensions to be developed without touching the core application. It’s a very convenient way for adding specific functionalities and we can therefore find tons of addons, e.g. an SMS module for 2-Factor-Authentication. The same principle applies for the main Keycloak code repo, and we’ve been able to suggest a PR on a metrics plugin, which is handy!

Just the beginning

We’ve now rolled out Keycloak on our whole µservices ecosystem and plugged in many of our back-office UIs. A bigger task awaits us now in wiring it for the main customer website, accessed by nearly 10 million active customers. We’re also exploring built-in UMA2.0 capability to address some more complex use cases involving authorization sharing.

--

--