The concept of zero-trust security is relatively simple. In essence, no entity or system should have trust by default. You should assume that any system you are talking to is not trustworthy until you establish otherwise. Within Kong Konnect, one mechanism to apply zero-trust is the OpenID Connect API gateway plugin.
In this post and the below recording from our Destination: Zero-Trust virtual event, I'll cover OpenID at a high level and some of its applications and use cases.
What Is OpenID Connect?
OpenID Connect is a standard built on top of OAuth and JWT (JSON Web Token). Chances are, you’ve already used OAuth and OpenID Connect. For example, if you’ve used your Google account to log into a web application, logging in with your Google account authorizes a system to do something with resources that belong to you.
OpenID Connect takes this a step further and introduces authentication, which means now it’s almost like a passport. The system you interact with can determine who you are.
Additionally, the standard introduces some other functionality, such as session management. That way, if you’re accessing resources like an API more than once, you don’t need to apply API gateway authentication and authorization every single time you use the API.
What Can OpenID Connect Do for APIs?
In the context of protecting APIs, you can tell the APIs who you are. You can also help those microservices and APIs figure out what you can or cannot do. In short, that's authentication and authorization.
Why Is OpenID Connect Good for API Security?
There are other mechanisms APIs can use to establish if a client may use them. Digital certificates, for example, are common. You may have already heard of using API keys and all the caveats that come with it. OpenID Connect is a widely adopted standard that a lot of providers out there implement.
An identity provider centralizes all the access controls. That means you don’t have to define and manage access controls and the consumers repeatedly across the API gateway and all your systems. Instead, you rely on the IdP for this in a centralized manner. For example, if someone leaves the company, you can go to one place to remove their access from your systems.
Furthermore, you have an opportunity to reduce risks. I mentioned earlier using API keys, which can be a thing of the past. Instead, with OpenID Connect, you’ll typically have the access token issued to you. The access token is a short-lived credential used for some time and then is no longer useful. In the event of a leaked access token, that access token only has a certain lifetime, and once it’s over, it’s not something that other systems can exploit.
How Can You Use The OpenID Connect API Gateway Plugin?
You can leverage OpenID Connect for many support flows, including:
I will begin by showing you the authorization code flow. From there, I'll switch to a bearer token, another mechanism that a consumer can use to identify themselves through the API gateway. And finally, I'll do something interesting: A header injection. That’s a bit of information useful to an upstream service when dealing with the consumer.
Before I jump into this, I want to warn you that OpenID Connect can be a little complex. If you go read any of the documentation or specifications, don’t be surprised if you see terms you don't recognize.
Identity Provider (IdP)/Authorization Service (AS)/Secure Token Service (STS), Issuer (ISS): Usually called the provider, such as AWS Cognito, Azure AD, Google Identity, Okta, Auth0, IdentityServer4, Keycloak, etc.
Resource Owner (RO): The end-user, or consumer, trying to access a resource/service/API
Resource Server (RS): The server where a resource resides, usually the upstream service/API
Relying Party (RP): A server providing access to a secure software application (for example, Kong Konnect)
OpenID Connect Flow Example
The above diagram shows a sample use case of the many flows that OpenID Connect can help you implement. In this diagram, the actors in the flow include:
A consumer that wants to utilize some type of API
An upstream name that you can use interchangeably with an API or microservice
The APIgateway where you can do all of the protections for those upstream services
The OpenID Connectidentity provider will help the proxy figure out if the consumer can or cannot access those upstream services
The above is one flow. Let's take a look at another.
Authorization Code Flow
The authorization code flow would go something like this:
The client application requests access to the API gateway.
The API gateway directs the client to the IdP.
The client exchanges information with the IdP.
The IdP redirects the client to the API gateway with its access token.
The API gateway validates the access token.
The gateway lets the client through to access the upstream service.
First, I'll show you the API gateway, configurations for an upstream service and how to protect it. If you’re not familiar with this user interface, don't worry; this is Kong's administrative user interface. Here, you can register all of your upstream services. Then you can decide how to expose them. And once you choose how to expose them, you can apply policies.
In this case, I’ll show you a policy specifically for working with an identity provider called Keycloak. Keycloak protects anyone who tries to access this path.
A typical consumer will go to the API gateway to request the path to a service. In this example, I'm demonstrating person-to-machine communication. The machine will authenticate and authorize the person. So I’ll go ahead and put my username and my password. Notice that I got redirected from the proxy. And once I logged in, I'm redirected back to the proxy. Also, notice there's this access token in the response. That is the identity provider telling the proxy the information it knows about this person.
It’s using the standard JWT. We can view it at jwt.io. It’s a self-contained envelope, and you can see all the information that identifies the person who’s trying to consume the service. Notice, for example, that you can see the same email address that I put during the login page.
In this example, assume you already have an access token, and you want the API gateway to let you through without having to go to the IdP again. I'll use Insomnia to test this use case.
Go to the API gateway and get an access token via the usual method UID/PW.
Use that access token from the IdP to pass into the API gateway via Insomnia.
The API gateway takes the access token and figures out who I am.
The API gateway lets me through.
Upstream Header Injection
For the last use case, assume that there is something in the information you know about the user that may be necessary for an upstream service to access. If you take a look over this access token, you will see that you have the scope (which can indicate applications to which this user has access). Remember, I talked about authentication and authorization. Here's an example of applying authorization. The API gateway has access to this information; what if you can extract it and give it to a service upstream?
I will modify the OpenID Connect API gateway plugin configuration to inject this information. It will make it visible here. I don't see it right now when I search for scope; it is empty. But once I modify the configuration so that I can let that upstream service get that information, it will be visible.
We will add the "Header Claims" and "Header Names." options in the configuration settings. Now we save and update my configuration.
If I try to re-access this API, I will now have a scope available for me that matches what the bearer token contained. That means whatever upstream service I was working with now has this information too.
Speed Up Zero-Trust Security With The OpenID Connect API Gateway Plugin
There is a benefit here. You don’t have to rewrite or maintain the code over and over. And that makes it faster for the developers of the upstream services to get their work done.