Microservices: integrating kong api gateway with Auth0 authentication provider

Vyacheslav Voronenko
8 min readMar 29, 2020

--

I used to work with several startups recently. Authentication is present in any product you do. Authentication is not simple. Not hard in the development sense well-defined standards such as OAuth2 are complete, extensively documented and supported by an ecosystem of tooling.

Rather, authentication is hard to get right sometimes. There are number of limitations like time constraints, product owner concentrated on other features, budget constraints and so on. If you have some previously developed user subsystem which evolves from project to project — that is cool. Otherwise you are about to start yet another authentication subsystem for your project. Story starts… Stored your passwords as an MD5 hash instead of, saying, using bcrypt and salt — tadamm. Didn’t force HTTP Strict Transport Security (HSTS) and get down-grade tadamm. Rookie mistakes, few sprints to polish.

But what if short term you need to comply with some of the security standards, like ISO27001/ISO27018, SOC II, HIPAA, PCI DSS etc? Implementation time grows while you need to implement your MVP instead.

So Auth0 is authentication as a service solution, which offloads your pain with authentication for a while, and allows to delay your own implementation, while immediately start using your application with robust authentication approach.

API gateway. The same situation in a modern world. You want to have lightweight api, so you want to offload number of checks to some middle-ware while keep solution as modular as possible. Most of the major cloud providers have their solution (like AWS API gateway), but if you want to stay provider independent you again have less choices — either implement api gateway on your own, or use some opensource solution. Here comes kong — makes connecting APIs and micro-services across hybrid or multi-cloud environments easier and faster. Not, that Kong gateway is the open source API gateway, built for multi-cloud and hybrid, and optimized for micro-services and distributed architectures. It is built on top of a lightweight proxy(nginx + lua) to deliver unparalleled latency, performance and scalability for all your micro-service applications regardless of where they run. It also allows flexibility by introducing granular control over your traffic with Kong’s plugin architecture.

Often you have situation, when you have separate api gateway, optional separate client portal and delegated authentication to Auth0… And here comes purpose of this article — illustrate proof of concept of combining Auth0, Kong and your portal in one architecture. Unfortunately, by this time in number of situations — swiss knife of proven plugins is needed to make kong to work nicely in a non-standard architecture solutions.

Generally, there are two possible flows: you are going to consume services interactively from some web portal — in that scenario customer logs on it’s own and consumes api directly from api gateway, or your api are about to be consumed on your server-side and then proxied to client of the your portal.

Let’s review both approaches.

Web application (interactive customer login to api gateway via browser UI)

This flow supposes, that API accessible through kong will be consumed by some browser application, while user management and authorization is delegated to some openid2 compatible third party service, in our case Auth0.

To accomplish this, one of the Nokia teams implemented plugin kong-oidc available at https://github.com/nokia/kong-oidc. Kong-oidc is a plugin for Kong implementing the OpenID Connect Relying Party (RP) functionality.

This plugin should be preinstalled on a kong VM or container.

On Auth0 interface lets create SPA application.

For further ideas, check advanced settings, and ensure that you can add up to 10 255 byte long custom value pairs, that will be later passed to your api behind kong.

In most of situations, you would like to pass some application specific info from your authentication provider to your api endpoint. To accomplish this, Auth0 has rules concept, on a UI you can find Rules section, where you can implement number of java-script routines with custom logic, that may add number of real-time parameters to the request passed.

In a example above note, that any additional parameters should follow uri scheme, in other case they will not be passed downstream ( someattr1, someattr2) in snippet above.

In that scenario you will have some web application running at some domain. Let’s assume, it is http://app.lvh.voronenko.net/ — it has some custom portal logic, but also consumes data from micro-services hosted behind kong, running at endpoint http://app.lvh.voronenko.net:8000/

Lets mock it:

Create the service

Create route, service will be exposed at {{ domain }}/spa/

If everything ok, you should get at /spa/ endpoint copy of the enhanced request received.

Now lets protect our endpoint with auth0 authentication. We will need to get three additional parameters: client id, client secret and discovery file. All can be obtained directly from auth0.

If you open spa discovery url, you will find, generally, “contract” supported by authentication provider, auth0

Let’s associate plugin with the service

If you check documentations of the plugins, you will note that it has number of customizations, that allows redirecting to proper pages of your main portal after login and so on.

Additionally, we need to inform auth0 about callbacks used. If your application does not have own, kong can provide default ones, which would reside under /cb

Now, if you would try to navigate to {{ domain_endpoint }}/spa/, you will get redirected to auth0, where you can login with credentials given, including social logins.

Upon successful login we are redirected back to kong, and now

As we see, now user is authorized to use or API in kong, and oidc plugin also adds special header called X-Userinfo, which contains base64 encoded jwt token. At the same moment, plugin performs validation of the token signature, and also can be configured to do more background checks.

You can decode base64 decode to view token data insides, pay attention to presence of the custom attributes.

The same does your code server-side in a micro-service or any next plugin in a chain and performs necessary actions basing on information received.

So with kong oidc plugin flow looks like

Some interesting discussion can be also found on https://github.com/nokia/kong-oidc/issues/15

And the same information can be now extracted by next plugin in chain or end service.

Note, that there is some mess with rules and hooks, as discussed in that thread https://community.auth0.com/t/custom-claims-not-added-to-access-token-despite-rule/9460/19

https://auth0.com/docs/api-auth/tutorials/client-credentials/customize-with-hooks

M2M application (non-interactive scripts)

This time we create another type — machine to machine application, and link it with api created in Web application flow, it is usual situation for consumers of your service implemented on some server side.

Let’s create direct route service

Organize route for the service

Now associate jwt plugin with service.

Now call to api will return 401 Unauthorized

How can we consume api ? We need to configure jwt consumer.

First of all, we need to get private key for message signing,

Having that key, lets create kong consumer

and specify jwt method of the authentication for him:

At that moment we are ready to consume our api behind kong.

First of all, user obtains access token from Auth0:

with response kind of

This request now passes, our API gets consumed.

Additionally. we get bunch of headers:

Header after Bearer is again our jwt token, that can be decoded.

and later consumed by our API.

Extending Autho metadata

Hooks

For M2M applications in difference to web based applications, where custom attributes can be injected via rules, point of extension are hooks.

Related documentation: https://auth0.com/docs/hooks

Take a look on a example below representing dummy Client Credentials Exchange hook extending access_token with additional key-pair'https://foo.com/claim': bar and somehookattr: somehookattrvalue

upon issuing request for token

we receive following response

Using debugger at jwt.io lets decode payload

Important: note, that extension attributes passed via custom name spaced uri was allowed, while un-namespaced custom attribute somehookattr was stripped out from the payload.

Known issues

No credentials found for given ‘iss’

Please check, that iss returned in token payload, should match to key field of the jwt token

In example above, "iss": "https://voronenko.auth0.com/" matches to key attribute of the jwt key.

What’s next?

If you start with kong with auth0, you will note, that in number of situations you would not be able to find flow of plugins that ideally suits your needs. Fortunately that is not a dead lock, as you always can write your own kong plugin — and this task is not so hard

Own plugin first steps

First step you need is to follow good boilerplate. Current recommended boilerplate for kong plugin can be found at https://github.com/Kong/kong-plugin where you can look for ideas

Own plugin implementation

Per my experience — success key with kong plugin development — is strict test driven development, and addressing all compiler warnings. Take a look on a https://github.com/Voronenko/kong-plugin-sa-jwt-claims-validate plugin as an example — which was implemented to accomplish specific jwt token data validations and thus offload micro-services behind.

Usual plugin is compact: ig could consists just of two files — `schema.lua` , which describes “configuration” contract for the plugin. You can keep validations simple while you are the only consumer of the plugin, but per my experience you would like to invest more efforts into configuration validation once you start targeting wider audience. Reasoning is that it is harder troubleshooting of misbehaved plugin in a production environment, if plugin fails on a configuration (consumer provides wrong configuration options, but that is not handled by schema validations), it could be also not clearly seen in kong logs.

Second file is `handler.lua` — you would need to implement few hooks according to your plugin logic. Important parts to pay attention to:

plugin priority — as it controls order of your plugin execution in chain of other plugins during the request processing

and access callback, which is the one that will be implemented in every custom plugin.

During callbacks implementation, pay attention to scope of the variables in lua — accidental exposing variable globally might lead to unexpected issues during concurrent calls. You might also want to introduce detailed logging activated using plugin configuration.

By that moment it is the end for the introduction with Auth0 , kong and your custom plugin. Good luck in your journey. Dockerized environment can be found at https://github.com/Voronenko/kong-compose-template/

--

--

Vyacheslav Voronenko

Software engineer, with project management background. Founder @ softasap.com — cool automation for the people :) — have a problem that needs to be solved?