In Part 1, we talked about the difference between the two built in Azure Kubernetes Roles, and when you are granted access to your AKS cluster via the “Azure Kubernetes Service Cluster User Role” role, you have to go through this interactive login flow to access resources in your cluster.
In this Part we are going to examine some of the concepts and protocols involved in this flow.
Before we talk about OAuth2, let’s have a look at the problem it solves.
In the early days of the web, you may have come across websites with the above section on their pages. This allowed users to tell their email contacts about this new webpage called MyCoolApp.
Behind the scenes, when you entered your gmail username and password, MyCoolApp would
- POST a request with your username and password to accounts.google.com to get an Authorization token.
- Using this token, it would then get all your gmail contacts
- It would then email each of them about MyCoolApp
- It would then forget your email and password, RIGHT?
Obviously this is not ideal!
Enter OAuth2. OAuth2 is a protocol to address this problem. You want to give an application (MyCoolApp) in which you are signed into, access to resources (contacts) of another web application (Gmail).
Let’s walk through OAuth2 with an example.
- You are signed in to MyCoolApp and you click on the button to Tell your Gmail Contacts about MyCoolApp.
- A popup appears with a login screen to your Google Account. You are happy it’s google by clicking the padlock and checking it’s cert if signed by a trusted signing company. So enter your gmail username and password and click Login
- Now you are presented with a screen (in the same popup) with a list of Google resources that MyCoolApp wants access to. If you tick the box and accept, you will be redirected back to a MyCoolApp API (callback) with an Authorization Code in the URL.
- MyCoolApp will now use this Code along with it’s own Google Client ID and Secret to request an Access Token.
- MyCoolApp will then use this access token, to access you gmail contacts.
As you can see, nowhere do you provide your google credentials to MyCoolApp, but MyCoolApp can successfully access your gmail contacts ONLY with your permission.
Now let’s identify some of the terminology involved in the above flow.
The Client ID identifies MyCoolApp to Google. MyCoolApp would have obtained this Client ID and Secret when it initially registered itself as an Application with Google OAuth2 Servers.
The Resource identifies the resource(s) you are trying to get access to, in this case it’s the gmail contacts
The Resource Owner is the user who owns the gmail contacts
The Scope of the resource MyCoolApp is trying to access is to Read Gmail Contacts
The Grant or Resource Type identifies the OAuth2 flow when retrieving an access token. In our case, MyCoolApp first gets an Authorization code, which it exchanges for an access token.
The Authorization Server is Goolges OAuth2 servers.
The Redirect ID identifies the MyCoolApp URL that Google should redirect to, to send the Authorization code to.
The Authorization Code is a code which Google will send back to MyCoolApp via the Redirect URL. MyCoolApp can then exchange this code along with it’s Client ID and Client secret for an Access Token. The reason for the Authorization code is that the code is returned via the url and has the potential to be viewed by a third party, but is useless without the client id and client secret that only MyCoolApp has.
The Access Token is what MyCoolApp will use to directly hit the Gmail API to get a list of contacts for the logged in user.
Open ID Connect
So while OAuth2 is used for Authorization, a layer developed on top of the OAuth2 protocol called Open ID Connect uses the OAuth2 flows for Authentication.
Let’s walk through this flow with an example.
In this scenario, we have an app called MyCoolApp. MyCoolApp doesn’t have it’s own Authentication process for users of it’s app, as it’s doesn’t want to manage the burden of storing passwords and all the requirements that sometimes goes with that e.g. encryption, hashes, compliance audit etc.
So MyCoolApp can use an Authorization and Authentication Server like Google to sign users up to it’s app or sign users into it’s app, and this relies on the Authorization Server using Open ID Connect for Authentication.
- MyCoolApp has a button to Log a User in with Google. The users clicks this button.
- The user is redirected to to Google’s Account Login page, and they user is satisfied this is really Googles Login page, so they enter their Google username and password.
- Next they are directed to a similar screen as before, but this time, it’s asking for MyCoolApp to have access to Read your Profile. This usually will give access to information like your first and second name, your email address and perhaps your birthday etc.
- If you tick the box and accept, as before, an Authorization code is sent back to the MyCoolApp Redirect URL.
- MyCoolApp then exchanges this Authorization Code for an ID Token (also called a JWT (JSON Web Token) token).
- Now this ID token identifies information about your, which are called Claims. These are claims about your identity. MyCoolApp can then use this ID token as a way of identifying you as a user of their application.
MyCoolApp can verify that this token is valid, by asking Google’s OAuth2 Servers to validate.
Two new pieces of Terminology are introduced in this Authentication flow that differ from the Authorization flow:
The Scope in this case is openid/Sign in and Read Profile
Instead of an Access Token, we have an ID Token (although it may still be called an Access Token in some places).
JSON Web Token (JWT)
In the last section we mentioned that the ID token is also known as a JWT token and we mentioned it contains a number of claims about a user. So let’s look at the makeup of a JWT token.
If you navigate to jwt.io and scroll down the page a small bit, you will see an example of the JWT token string.
It contains 3 parts of base64 data, each part separated by a dot.
The first section is known as the header, and may contain a number of header claims about this token, like the type of token, the algorithm used to encode the signature etc.
The second section is known as the payload and this section contains a number of claims about the identity in this token.
The last section is known as the signature, and is an encoded section containing the header, payload and secret only know to the Authorization Server.
So now if we ’s first extract the access token (ID token) from an AKS Kubeconfig file and paste it into jwt.io, we can see the decoded payload section claims.
aud identifies the audience. The audience allows us to specify what resource this ID token will be used against. In our case this token will be used to identity us as a user against the kubernetes api server (server app). This will make more sense when we talk about client and server apps in the Part 3.
appid identifies the client that was used to generate the ID token. So when we talked about the OAuth2 Open ID Connect flow, remember we had the client which was acting on the users behalf.
groups identifies all the AD Groups that this user/identity is a part of.
upn identifies the Unique Principal Name of this identity
Now when we think about RBAC in an AKS cluster, you can image you can assign a UPN or an AD Group access to certain resources in your Kubernetes Cluster using Roles and RoleBindings, which is how you can allow access to certain resources.
Microsoft Identity Platform
In the previous examples, I used Google’s OAuth2 servers, but for Azure and AKS, Microsoft have their own OAuth2 and OIDC implementation as part of their Microsoft Identify Platform.
Using the Microsoft Identify Platform, we can use our Azure Active Directory Identities that are part of our Tenant to Authenticate ourselves as well as assign these identities specific roles (Azure Kubernetes Service Cluster User Role) to access Microsoft Resources (AKS).
Ok hopefully the above has opened your eyes to Authentication and OIDC. OIDC forms the basis of how we authenticate ourselves to and AKS cluster. Now we’re ready for Part 3, where we’ll talk about the Client and Server Tenant Apps that enable the mapping of users/groups in our Azure Tenant to Roles in our AKS Cluster. We’ll talk about the flows and interactions between these apps and the Microsoft Identity Platform and the AKS Cluster, as well as talk about the Identity fields inside the Kubeconfig file.