EKS Anywhere., validating KeyCloak OIDC SSO access to clusters for kubectl

Ambar Hassani
7 min readJul 27, 2022

This article is part of the series EKS Anywhere, extending the Hybrid cloud momentum | by Ambar Hassani | Apr, 2022 | Medium

In the previous two related articles, we have already setup the KeyCloak server and also configured our EKS Anywhere cluster for OIDC access.

In this article, we will observe how to access the OIDC enabled cluster via kubectl. While there are many plugins/methods available to do so., it largely depends on whether you prefer a browser based or a browserless authentication method to access the cluster. We will document the latter (browserless) method as it greatly simplifies the challenges one would face in case of logins via jump hosts or where browser-based authentications are not feasible.

We can test the below procedure right from the EKS Anywhere Administrative machine as it already has kubectl installed. Alternatively, in this specific example, I will assume a developer machine with WSL2 Ubuntu installed with kubectl.

The main goal is to create the kubectl contexts for various users and validate access levels. Recall our RBAC arrangement (oidc user/groups, k8s rbac role mappings) via the previous two articles

  • user-admin | kube-admin |cluster-admin role
  • user-dev | kube-dev | edit role
  • user-view-only | kube-view-only | view role

Let’s begin by performing the below procedure on any Linux machine which has kubectl installed.

  • Create a new file named create-oidc-contexts.sh under $HOME and make it executable
  • Copy and paste the contents of the below given raw gist to the above created file

https://gist.github.com/thecloudgarage/fdf0cdc89a49ed0fcf75c19b69e5eb8e

Repeat the below script for each of the OIDC user & cluster pairs. In this case, since we have only one cluster and 3 users, a total of 3 contexts needs to be created, i.e., the below script needs to be run thrice with each of the OIDC usernames. Repeat the script for additional clusters & user pairs.

source $HOME/create-oidc-contexts.sh
The script will prompt you for the below parameters on a per context basis. I have provided my setup's parameters. Yours could be different depending on what you have set the values in the previous two exercises (KeyCloak server setup and OIDC enablement on EKS Anywhere cluster)
* oidcClusterName: oidctestcluster01
* fqdnOfKeyCloakServer: keycloak.thecloudgarage.com
* oidcClientId: kube (yours will be the same)
* oidcClientSecret: kube-client-secret (yours will be the same)
* oidcUsername: user-admin or user-dev or user-view-only
* oidcPassword: user-admin or user-dev or user-view-only
* apiServerEndpoint: 172.24.165.11 (yours will be different)

Let’s observe the actual execution of this script in my machine as I intend to access the EKS Anywhere cluster named testwk01 which is configured for KeyCloak SSO OIDC

NOTE:

  • The client secret for all contexts will be kube-client-secret
  • The password for OIDC users is same as the username

Let’s create the context for user-admin and oidctestcluster01 cluster

source create-oidc-contexts.sh
Input OIDC enabled cluster name for kubectl context
oidClusterName: oidctestcluster01
Input your OIDC servers FQDN
fqdnOfKeyCloakServer: keycloak.thecloudgarage.com
Input your OIDC client id
oidcClientId: kube
Input your OIDC Secret
oidcClientSecret:
Input your OIDC Username
oidcUsername: user-admin
Input your OIDC Password
oidcPassword:
Provide the API server endpoint in the format https://172.24.165.11:6443
Ensure that https and port number 6443 is mentioned as specififed in the above format
Only in cases e.g. eks public clusters, you can omit the port number as it provides a load-balancer URL
apiServerEndpoint: https://172.24.165.11:6443
Cluster "oidctestcluster01" set.
depth=0 C = IN, ST = MH, L = Mumbai, O = stack, OU = devops, CN = keycloak.thecloudgarage.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = IN, ST = MH, L = Mumbai, O = stack, OU = devops, CN = keycloak.thecloudgarage.com
verify error:num=21:unable to verify the first certificate
verify return:1
DONE
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3816 100 3673 100 143 29861 1162 --:--:-- --:--:-- --:--:-- 31024
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3816 100 3673 100 143 31127 1211 --:--:-- --:--:-- --:--:-- 32338
deleted user user-admin from /home/ubuntu/.kube/config
warning: this removed your active context, use "kubectl config use-context" to select a different one
deleted context user-admin-oidctestcluster01 from /home/ubuntu/.kube/config
Property "current-context" unset.
User "user-admin" set.
Context "user-admin-oidctestcluster01" created.
Switched to context "user-admin-oidctestcluster01".

Let’s create the context for user-dev and oidctestcluster01 cluster

source create-oidc-contexts.sh
Input OIDC enabled cluster name for kubectl context
oidClusterName: oidctestcluster01
Input your OIDC servers FQDN
fqdnOfKeyCloakServer: keycloak.thecloudgarage.com
Input your OIDC client id
oidcClientId: kube
Input your OIDC Secret
oidcClientSecret:
Input your OIDC Username
oidcUsername: user-dev
Input your OIDC Password
oidcPassword:
Provide the API server endpoint in the format https://172.24.165.11:6443
Ensure that https and port number 6443 is mentioned as specififed in the above format
Only in cases e.g. eks public clusters, you can omit the port number as it provides a load-balancer URL
apiServerEndpoint: https://172.24.165.12:6443
Cluster "oidctestcluster01" set.
depth=0 C = IN, ST = MH, L = Mumbai, O = stack, OU = devops, CN = keycloak.thecloudgarage.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = IN, ST = MH, L = Mumbai, O = stack, OU = devops, CN = keycloak.thecloudgarage.com
verify error:num=21:unable to verify the first certificate
verify return:1
DONE
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3774 100 3635 100 139 28849 1103 --:--:-- --:--:-- --:--:-- 29952
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3774 100 3635 100 139 29795 1139 --:--:-- --:--:-- --:--:-- 30934
deleted user user-dev from /home/ubuntu/.kube/config
deleted context user-dev-oidctestcluster01 from /home/ubuntu/.kube/config
Property "current-context" unset.
User "user-dev" set.
Context "user-dev-oidctestcluster01" created.
Switched to context "user-dev-oidctestcluster01".

And lastly for user-view-only and cluster oidctestcluster01

source create-oidc-contexts.sh
Input OIDC enabled cluster name for kubectl context
oidClusterName: oidctestcluster01
Input your OIDC servers FQDN
fqdnOfKeyCloakServer: keycloak.thecloudgarage.com
Input your OIDC client id
oidcClientId: kube
Input your OIDC Secret
oidcClientSecret:
Input your OIDC Username
oidcUsername: user-view-only
Input your OIDC Password
oidcPassword:
Provide the API server endpoint in the format https://172.24.165.11:6443
Ensure that https and port number 6443 is mentioned as specififed in the above format
Only in cases e.g. eks public clusters, you can omit the port number as it provides a load-balancer URL
apiServerEndpoint: https://172.24.165.12:6443
Cluster "oidctestcluster01" set.
depth=0 C = IN, ST = MH, L = Mumbai, O = stack, OU = devops, CN = keycloak.thecloudgarage.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = IN, ST = MH, L = Mumbai, O = stack, OU = devops, CN = keycloak.thecloudgarage.com
verify error:num=21:unable to verify the first certificate
verify return:1
DONE
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3898 100 3747 100 151 31487 1268 --:--:-- --:--:-- --:--:-- 32756
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3898 100 3747 100 151 31225 1258 --:--:-- --:--:-- --:--:-- 32483
deleted user user-view-only from /home/ubuntu/.kube/config
deleted context user-view-only-oidctestcluster01 from /home/ubuntu/.kube/config
Property "current-context" unset.
User "user-view-only" set.
Context "user-view-only-oidctestcluster01" created.
Switched to context "user-view-only-oidctestcluster01".

Now that all the three contexts are set., we can verify them in our kube config file

KUBECONFIG=$HOME/.kube/config
kubectl config get-contexts
KUBECONFIG=$HOME/.kube/config
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
user-admin-oidctestcluster01 oidctestcluster01 user-admin
user-dev-oidctestcluster01 oidctestcluster01 user-dev
* user-view-only-oidctestcluster01 oidctestcluster01 user-view-only

Let’s start validating the access levels by switching the contexts

Let’s begin by switching context to user-admin that has a cluster role of cluster-admin. We can see that this context can create namespaces and retrieve node information

kubectl config use-context user-admin-oidctestcluster01
Switched to context "user-admin-oidctestcluster01".
kubectl create namespace testone
namespace/testone created
kubectl get nodes
NAME STATUS ROLES AGE VERSION
oidctestcluster01-ftqg7 Ready control-plane,master 18h v1.21.13-eks-b88cc51
oidctestcluster01-kv7q6 Ready control-plane,master 18h v1.21.13-eks-b88cc51
oidctestcluster01-md-0-7595c49d8d-5vc59 Ready <none> 18h v1.21.13-eks-b88cc51
oidctestcluster01-md-0-7595c49d8d-6khmx Ready <none> 18h v1.21.13-eks-b88cc51

Next let’s switch the context to user-dev which has a cluster role of edit. As you can see that this role restricts the permissions model to certain actions as implicitly defined in the default “edit” role

kubectl config use-context user-dev-oidctestcluster01
Switched to context "user-dev-oidctestcluster01".
kubectl get namespace
NAME STATUS AGE
default Active 18h
kube-node-lease Active 18h
kube-public Active 18h
kube-system Active 18h
testone Active 3m27s
kubectl create namespace testtwo
Error from server (Forbidden): namespaces is forbidden: User "user-dev@emaildomainname" cannot create resource "namespaces" in API group "" at the cluster scope
kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "user-dev@emaildomainname" cannot list resource "nodes" in API group "" at the cluster scope
kubectl get pods
No resources found in default namespace.

Lastly, let’s switch the context to user-dev. Likewise, as per the permissions implicit to the default “view” cluster role, the user can only perform certain restricted actions

kubectl config use-context user-view-only-oidctestcluster01
Switched to context "user-view-only-oidctestcluster01".
kubectl get namespace
NAME STATUS AGE
default Active 18h
kube-node-lease Active 18h
kube-public Active 18h
kube-system Active 18h
testone Active 6m25s
kubectl get pods
No resources found in default namespace.
kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "user-view-only@emaildomainname" cannot list resource "nodes" in API group "" at the cluster scope

That’s it! Hopefully, you would have understood the interaction model between EKS Anywhere clusters & KeyCloak SSO OIDC., and how you can effectively create organization wide policy derivatives to secure Kubernetes access

cheers

Ambar@thecloudgarage

#iwork4dell

--

--

Ambar Hassani

24+ years of blended experience of technology & people leadership, startup management and disruptive acceleration/adoption of next-gen technologies