{"id":20694,"date":"2022-12-22T09:22:14","date_gmt":"2022-12-22T08:22:14","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=20694"},"modified":"2024-09-10T15:45:35","modified_gmt":"2024-09-10T13:45:35","slug":"kubernetes-sso-using-azure-ad","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/","title":{"rendered":"Kubernetes SSO using Azure AD"},"content":{"rendered":"\n<p>I&#8217;ve worked on this project to authenticate Kubernetes users against Azure AD and so have Single Sign-On (SSO). That was a long journey on a rocky road and it&#8217;s worth summarising in this blog all the steps required to make it done. I didn&#8217;t find the Kubernetes and Azure documentation helpful enough to make it work straight away. I had to collect chunks of information here and there to build a working solution and  you will find here information I didn&#8217;t see anywhere else on the Web. If you too need to configure SSO with Azure AD, you&#8217;re in the right place and I&#8217;ll share everything I&#8217;ve learned to help you set it up!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The starting point<\/h2>\n\n\n\n<p>Our cluster is an OnPrem Kubernetes cluster (so we are not using AKS &#8211; the Azure Kubernetes solution &#8211; on which most documentation relates) and the Azure configuration part is done in our case by a dedicated team.<\/p>\n\n\n\n<p>In Azure you&#8217;ll need to register an application, set a Redirect URI (web page and path used for authentication) and take note of the Application ID, Client ID and Client Secret generated by this new registration. You&#8217;ll need those when configuring Kubernetes to interact with Azure AD. Of course you&#8217;ll also need an Azure AD account which is an email address and a password.<\/p>\n\n\n\n<p>On the Kubernetes side, we do the configuration on the Master node of this cluster and there are 2 places where you will configure this interaction with Azure AD: The <strong>\/etc\/kubernetes\/manifests\/kube-apiserver.yaml<\/strong> file and the <strong>.kube\/config<\/strong> file used by kubectl. Sounds easy right? Buckle up we are entering a zone of turbulence!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The deprecated method<\/h2>\n\n\n\n<p>This method is the first I&#8217;ve found and tried. In Azure you have to register 2 Applications in Azure AD: One for Kubernetes and one for kubectl.<\/p>\n\n\n\n<p>On the Kubernetes side the configuration is as follows:<\/p>\n\n\n\n<p><strong>kube-apiserver.yaml<\/strong> uses the Azure Kubernetes Application registration information:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\n    - --oidc-client-id=...\n    - --oidc-issuer-url=https:\/\/sts.windows.net\/...\/\n    - --oidc-username-claim=...\n<\/pre><\/div>\n\n\n<p>For the kubectl command fill the file <strong>.kube\/config<\/strong> using the Azure kubectl Application registration information:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl config set-credentials &lt;user_name&gt; \\\n--auth-provider=azure \\\n--auth-provider-arg=environment=AzurePublicCloud \\\n--auth-provider-arg=client-id=... \\\n--auth-provider-arg=client-secret=... \\\n--auth-provider-arg=tenant-id=... \\\n--auth-provider-arg=apiserver-id=...\n\n$ kubectl config set-context &lt;context_name&gt; \\\n--cluster=&lt;cluster_name&gt; \\\n--namespace=default \\\n--user=&lt;user_name&gt;\n<\/pre><\/div>\n\n\n<p>That looks pretty straightforward, so I&#8217;ve switched to this new context and got the following:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl config use-context &lt;context_name&gt;\n$ kubectl get pods -A\n\nW1118 10:00:38.620058 3523839 azure.go:92] WARNING: the azure auth plugin is deprecated in v1.22+, unavailable in v1.25+; use https:\/\/github.com\/Azure\/kubelogin instead.\nTo learn more, consult https:\/\/kubernetes.io\/docs\/reference\/access-authn-authz\/authentication\/#client-go-credential-plugins\nE1118 10:00:38.773424 3523839 azure.go:162] Failed to acquire a token: failed acquiring new token: initialing the device code authentication: autorest\/adal\/devicetoken: Error occurred while handling response from the Device Endpoint: Error HTTP status != 200\nUnable to connect to the server: acquiring a token for authorization header: failed acquiring new token: initialing the device code authentication: autorest\/adal\/devicetoken: Error occurred while handling response from the Device Endpoint: Error HTTP status != 200\n<\/pre><\/div>\n\n\n<p>I would need to dig deeper to make this work but what annoyed me was that this method is deprecated and so for a future proof solution I&#8217;ve started to look at kubelogin as recommended in the output above.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The future proof method &#8211; Authentication<\/h2>\n\n\n\n<p>With this method you only need to register one Application in Azure and take note of the same information as in the previous method.<\/p>\n\n\n\n<p>On the Kubernetes side, first I&#8217;ve installed <strong>krew<\/strong> the package manager for kubectl in order to install the oidc-login plugin:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ curl -fsSLO https:\/\/github.com\/kubernetes-sigs\/krew\/releases\/latest\/download\/krew-linux_amd64.tar.gz\n$ tar zxvf krew-linux_amd64.tar.gz\n$ .\/krew-linux_amd64 install krew\n$ kubectl krew update\n$ kubectl krew install oidc-login\n<\/pre><\/div>\n\n\n<p>Then I&#8217;ve configured Kubernetes as follows:<\/p>\n\n\n\n<p><strong>kube-apiserver.yaml<\/strong> uses the Azure Application registration information:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\n    - --oidc-client-id=...\n    - --oidc-issuer-url=https:\/\/sts.windows.net\/...\/\n    - --oidc-username-claim=...\n<\/pre><\/div>\n\n\n<p>This is the same config as with the deprecated method, however the kubectl parameters to fill in the <strong>.kube\/config<\/strong> file is now different:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nkubectl config set-credentials &lt;user_name&gt; \\\n--exec-api-version=client.authentication.k8s.io\/v1beta1 \\\n--exec-command=kubectl \\\n--exec-arg=kubectl-oidc_login \\\n--exec-arg=get-token \\\n--exec-arg=--oidc-issuer-url=&quot;https:\/\/sts.windows.net\/...\/&quot; \\\n--exec-arg=--oidc-client-id=... \\\n--exec-arg=--oidc-client-secret=...\n<\/pre><\/div>\n\n\n<p>Be careful to not put &#8221; &#8221; around your secret value otherwise it will not work as I will show you a bit further below.<\/p>\n\n\n\n<p>Now we are ready to initiate the authentication:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl-oidc_login get-token \\\n--oidc-issuer-url=&quot;https:\/\/sts.windows.net\/...\/&quot; \\\n--oidc-client-id=... \\\n--oidc-client-secret=&quot;...&quot;\n<\/pre><\/div>\n\n\n<p>Be careful here too, here you have to put &#8221; &#8221; around your secret value! Yes I&#8217;ve told you I&#8217;ll share everything with you and at this point with those information you will already save yourself severals days of headaches. But we are not done yet. Hang on tight!<\/p>\n\n\n\n<p>The result of the command above is as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nerror: could not open the browser: exec: &quot;xdg-open,x-www-browser,www-browser&quot;: executable file not found in $PATH\nPlease visit the following URL in your browser manually: http:\/\/localhost:8000\n<\/pre><\/div>\n\n\n<p>First if you only have command line access to this server, you can avoid the error above and configure to not try to open the web browser automatically by adding the parameter &#8211;grant-type=authcode-keyboard in the file <strong>.kube\/config<\/strong><\/p>\n\n\n\n<p>At this stage you need to open the URL http:\/\/localhost:8000 in a web browser on the Master node to enter your Azure credentials. In our configuration, the cluster nodes have no web browser as those nodes are only using a command line interface. This is where you need to be creative and for example configure Putty with a ssh tunnel in order for your Web browser on your office machine to connect directly to the cluster node on this port (L8000 localhost:8000). This is what we did for opening the URL in the web browser of our office machine. The first time you need to authenticate with your Azure AD credentials and then if succeeded, you&#8217;ll automatically get a token in your Master node terminal for a period of time as shown below:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n{&quot;kind&quot;:&quot;ExecCredential&quot;,&quot;apiVersion&quot;:&quot;client.authentication.k8s.io\/v1beta1&quot;,&quot;spec&quot;:{&quot;interactive&quot;:false},&quot;status&quot;:{&quot;expirationTimestamp&quot;:&quot;2022-11-25T10:20:43Z&quot;,&quot;token&quot;:&quot;eyJ0eXAiOi...&quot;}}\n<\/pre><\/div>\n\n\n<p>The URL you see in your terminal has to match the Redirect URI parameter of your application registration in Azure. You could also configure this URL in kubelogin and Redirect URI in your Azure application with a path that would be reachable from your office machine in order to perform this authentication (and avoid using an ssh tunneling from the Office machine to the Master node). Note that this path needs to use https:\/\/ (because http is only allowed by Azure for localhost). Keep a note of that as I&#8217;ll come back to this in the limitations section below.<\/p>\n\n\n\n<p>At this stage you are now authenticated.<\/p>\n\n\n\n<p>Before moving on, let&#8217;s take a look at this error you may encounter when trying to authenticate:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl get pods\nerror: could not open the browser: exec: &quot;xdg-open,x-www-browser,www-browser&quot;: executable file not found in $PATH\n\nPlease visit the following URL in your browser manually: http:\/\/localhost:8000\nerror: get-token: authentication error: authcode-browser error: authentication error: authorization code flow error: oauth2 error: could not exchange the code and token: oauth2: cannot fetch token: 401 Unauthorized\nResponse: {&quot;error&quot;:&quot;invalid_client&quot;,&quot;error_description&quot;:&quot;AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app &#039;...&#039;.\\r\\nTrace ID: ...\\r\\nCorrelation ID: ...\\r\\nTimestamp: 2022-11-25 07:46:29Z&quot;,&quot;error_codes&quot;:&#x5B;7000215],&quot;timestamp&quot;:&quot;2022-11-25 07:46:29Z&quot;,&quot;trace_id&quot;:&quot;d...&quot;,&quot;correlation_id&quot;:&quot;...&quot;,&quot;error_uri&quot;:&quot;https:\/\/login.windows.net\/error?code=7000215&quot;}\n<\/pre><\/div>\n\n\n<p>If you get this ugly error and you&#8217;re pretty sure you&#8217;ve set the client secret value properly then as written previously, remove the &#8221; &#8221; around this secret in the <strong>.kube\/config<\/strong> file and you&#8217;ll be good to go.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The future proof method &#8211; RBAC<\/h2>\n\n\n\n<p>You can then enter your kubectl commands:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl get pods\nError from server (Forbidden): pods is forbidden: User &quot;&lt;user_name&gt;&quot; cannot list resource &quot;pods&quot; in API group &quot;&quot; in the namespace &quot;default&quot;\n<\/pre><\/div>\n\n\n<p>Yes that is also an error but a beautiful one! This means you&#8217;ve passed the authentication stage for running kubectl commands! You just need to define some Role-Based Access Control (RBAC) for your user in order to specify what he can do and see in this cluster (authorization stage).<\/p>\n\n\n\n<p>For example you can configure a clusterrole and clusterrolebinding as follows in a yaml file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: test-sso-clusterrolebinding\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: test-sso-clusterrole\nsubjects:\n- apiGroup: rbac.authorization.k8s.io\n  kind: User\n  name: &quot;&lt;user_name&gt;&quot;\n\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n  name: test-sso-clusterrole\nrules:\n- apiGroups: &#x5B;&quot;&quot;] # &quot;&quot; indicates the core API group\n  resources: &#x5B;&quot;nodes&quot;, &quot;pods&quot;]\n  verbs: &#x5B;&quot;get&quot;, &quot;watch&quot;, &quot;list&quot;]\n<\/pre><\/div>\n\n\n<p>Apply this file and you&#8217;ll now see the results below:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl get secrets\nError from server (Forbidden): secrets is forbidden: User &quot;&lt;user_name&gt;&quot; cannot list resource &quot;secrets&quot; in API group &quot;&quot; in the namespace &quot;default&quot;\n\n$ kubectl get po\nNo resources found in default namespace.\n\n$ kubectl get no\nNAME    STATUS   ROLES           AGE   VERSION\nnode1   Ready    control-plane   9d    v1.24.4\nnode2   Ready    &lt;none&gt;          9d    v1.24.4\nnode3   Ready    &lt;none&gt;          9d    v1.24.4\nnode4   Ready    &lt;none&gt;          9d    v1.24.4\nnode5   Ready    &lt;none&gt;          9d    v1.24.4\nnode6   Ready    &lt;none&gt;          9d    v1.24.4\n<\/pre><\/div>\n\n\n<p>As expected, you can access only what is defined in your clusterrole\/clusterrolebinding.<\/p>\n\n\n\n<p>Hold on! Are you frustrated because maybe you couldn&#8217;t apply that yaml file right? No problem I&#8217;ll not let you down and let&#8217;s clear that up!<\/p>\n\n\n\n<p>If you are still using the context that uses SSO you don&#8217;t have access to the resources clusterrole and clusterrolebinding. If you&#8217;ve followed along this blog you should have 2 contexts: One that is accessing your cluster without SSO and one with it. You&#8217;ll then need first to switch to the context without SSO:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl config get-contexts\n$ kubectl config use-context &lt;context_without_SSO&gt;\n<\/pre><\/div>\n\n\n<p>Then apply your yaml file and switch back to your context with SSO in order to test those RBAC in action.<\/p>\n\n\n\n<p>It comes without saying that when your cluster will be fully configured you&#8217;ll need to remove that context without SSO otherwise your cluster security is deficient and all those efforts were for nothing!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Limitations &amp; Conclusion<\/h2>\n\n\n\n<p>I&#8217;ve talked about a limitation regarding the Redirect URI that supports only https in Azure.  Unfortunately the oidc plugin of kubectl seems to support only http&#8230; So here only the localhost URI as used in this blog can be used.<\/p>\n\n\n\n<p>If you don&#8217;t want to use the default localhost as the Redirect URL in kubectl you can play with the following parameters of the <strong>.kube\/config<\/strong> file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n - --listen-address=0.0.0.0:8000\n - --oidc-redirect-url-hostname=&lt;http url&gt;\n<\/pre><\/div>\n\n\n<p>By default the kubectl-oid process listen on the local IP address 127.0.0.1 so you can change it (and have to do it if you don&#8217;t want to use locahost as URL) with the listen-address parameter. You can check it afterwards as follows (you need to enter a kubectl command first in another terminal in order for the Redirect URL address to appear and the port to be put in the LISTEN state):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ netstat -anp|grep 8000\ntcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      3457640\/kubectl-oid\n<\/pre><\/div>\n\n\n<p>With this method you can then change the Redirect URL with something that is reachable from your office machine for example. However this URL must start with http as this can not be changed in the parameters of kubelogin. So we can&#8217;t use it with Azure as we can only use https and so there is a mismatch here.<\/p>\n\n\n\n<p>Another promising method we&#8217;ve tried is to use the following parameter in <strong>.kube\/config<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\n--grant-type=authcode-keyboard\n<\/pre><\/div>\n\n\n<p>You then get the following Redirect URL:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ kubectl get pods\nPlease visit the following URL in your browser: https:\/\/login.windows.net\/9b52ed8b...\nEnter code:\n<\/pre><\/div>\n\n\n<p>So we could authenticate from any computer in order to get this code and this is an https URL! But for this to work we need to add the following URL urn:ietf:wg:oauth:2.0:oob as Redirect URI in Azure. Unfortunately Azure doesn&#8217;t support it either! We must set an URI starting with https:\/\/ in Azure so we are stuck again.<\/p>\n\n\n\n<p>So the only working method is by authenticating using the URL http:\/\/localhost:&#8230; as this suits both kubelogin and Azure. To use something else we would need to insert kind of a proxy in the middle that could accomodate both sides.<\/p>\n\n\n\n<p>I&#8217;ll be happy if based on this blog you can follow along and make your configuration work right away. It took me several days to make it work, sort out what is needed and what is not, reading the experience of others and building up on the insightful ideas of my fantastic DevOps Team in dbi services.<\/p>\n\n\n\n<p>We just had a breakthrough (thank you <strong>Arnaud Berbier<\/strong>, our Mbapp\u00e9 in our DevOps Team!) and made this work using https with kubelogin! Stay tuned as I&#8217;ll share the details in a <a href=\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad-the-production-solution\/\" target=\"_blank\" rel=\"noreferrer noopener\">next blog<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve worked on this project to authenticate Kubernetes users against Azure AD and so have Single Sign-On (SSO). That was a long journey on a rocky road and it&#8217;s worth summarising in this blog all the steps required to make it done. I didn&#8217;t find the Kubernetes and Azure documentation helpful enough to make it [&hellip;]<\/p>\n","protected":false},"author":109,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3271,955,1320,1522],"tags":[995,1338,89,2764,2763,445],"type_dbi":[],"class_list":["post-20694","post","type-post","status-publish","format-standard","hentry","category-azure","category-cloud","category-devops","category-kubernetes","tag-authentication","tag-azure","tag-kubernetes","tag-oidc","tag-openid","tag-sso"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Kubernetes SSO using Azure AD - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Kubernetes SSO using Azure AD\" \/>\n<meta property=\"og:description\" content=\"I&#8217;ve worked on this project to authenticate Kubernetes users against Azure AD and so have Single Sign-On (SSO). That was a long journey on a rocky road and it&#8217;s worth summarising in this blog all the steps required to make it done. I didn&#8217;t find the Kubernetes and Azure documentation helpful enough to make it [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-22T08:22:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-10T13:45:35+00:00\" \/>\n<meta name=\"author\" content=\"DevOps\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"DevOps\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/\"},\"author\":{\"name\":\"DevOps\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4cd1b5f8a3de93f05a16ab8d7d2b7735\"},\"headline\":\"Kubernetes SSO using Azure AD\",\"datePublished\":\"2022-12-22T08:22:14+00:00\",\"dateModified\":\"2024-09-10T13:45:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/\"},\"wordCount\":1592,\"commentCount\":0,\"keywords\":[\"Authentication\",\"Azure\",\"kubernetes\",\"oidc\",\"openid\",\"SSO\"],\"articleSection\":[\"Azure\",\"Cloud\",\"DevOps\",\"Kubernetes\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/\",\"name\":\"Kubernetes SSO using Azure AD - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2022-12-22T08:22:14+00:00\",\"dateModified\":\"2024-09-10T13:45:35+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4cd1b5f8a3de93f05a16ab8d7d2b7735\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Kubernetes SSO using Azure AD\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4cd1b5f8a3de93f05a16ab8d7d2b7735\",\"name\":\"DevOps\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/cdd2dd7441774355062c0f0f68612296b059cd1e2ff6c7af0b15dba0ed64a85f?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cdd2dd7441774355062c0f0f68612296b059cd1e2ff6c7af0b15dba0ed64a85f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cdd2dd7441774355062c0f0f68612296b059cd1e2ff6c7af0b15dba0ed64a85f?s=96&d=mm&r=g\",\"caption\":\"DevOps\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/devops\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Kubernetes SSO using Azure AD - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/","og_locale":"en_US","og_type":"article","og_title":"Kubernetes SSO using Azure AD","og_description":"I&#8217;ve worked on this project to authenticate Kubernetes users against Azure AD and so have Single Sign-On (SSO). That was a long journey on a rocky road and it&#8217;s worth summarising in this blog all the steps required to make it done. I didn&#8217;t find the Kubernetes and Azure documentation helpful enough to make it [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/","og_site_name":"dbi Blog","article_published_time":"2022-12-22T08:22:14+00:00","article_modified_time":"2024-09-10T13:45:35+00:00","author":"DevOps","twitter_card":"summary_large_image","twitter_misc":{"Written by":"DevOps","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/"},"author":{"name":"DevOps","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4cd1b5f8a3de93f05a16ab8d7d2b7735"},"headline":"Kubernetes SSO using Azure AD","datePublished":"2022-12-22T08:22:14+00:00","dateModified":"2024-09-10T13:45:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/"},"wordCount":1592,"commentCount":0,"keywords":["Authentication","Azure","kubernetes","oidc","openid","SSO"],"articleSection":["Azure","Cloud","DevOps","Kubernetes"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/","url":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/","name":"Kubernetes SSO using Azure AD - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2022-12-22T08:22:14+00:00","dateModified":"2024-09-10T13:45:35+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4cd1b5f8a3de93f05a16ab8d7d2b7735"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/kubernetes-sso-using-azure-ad\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Kubernetes SSO using Azure AD"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4cd1b5f8a3de93f05a16ab8d7d2b7735","name":"DevOps","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/cdd2dd7441774355062c0f0f68612296b059cd1e2ff6c7af0b15dba0ed64a85f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/cdd2dd7441774355062c0f0f68612296b059cd1e2ff6c7af0b15dba0ed64a85f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cdd2dd7441774355062c0f0f68612296b059cd1e2ff6c7af0b15dba0ed64a85f?s=96&d=mm&r=g","caption":"DevOps"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/devops\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/20694","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/109"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=20694"}],"version-history":[{"count":24,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/20694\/revisions"}],"predecessor-version":[{"id":21413,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/20694\/revisions\/21413"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=20694"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=20694"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=20694"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=20694"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}