<p>I'm trying to set up SSO between our (regular, not AKS) kubernetes clusters and Azure AD.
Since I don't know how to forward the token to the kube-dashboard, I'm just currently trying with kubectl binary installed on my computer.
It works when no groups are involved, but we want to filter by security group (accounts on AAD are synced from our onprem Active Directory), no kube RBAC involved.</p>

<p>Setup is inspired by <a href="https://medium.com/@olemarkus/using-azure-ad-to-authenticate-to-kubernetes-eb143d3cce10" rel="nofollow noreferrer">https://medium.com/@olemarkus/using-azure-ad-to-authenticate-to-kubernetes-eb143d3cce10</a> and <a href="https://learn.microsoft.com/fr-fr/azure/aks/azure-ad-integration" rel="nofollow noreferrer">https://learn.microsoft.com/fr-fr/azure/aks/azure-ad-integration</a> :</p>

<ul>
<li>web app for kube api server configured to expose its API (add scope etc...) with app ID : <em>abc123</em></li>
<li>native app for client kubectl configured with addition of api permission from the web app, with app ID : <em>xyz456</em></li>
<li>kube api server yaml manifest , I add :</li>
</ul>

<p><code>- --oidc-client-id=spn:abc123</code></p>

<p><code>- --oidc-issuer-url=https://sts.windows.net/OurAADTenantID</code></p>

<ul>
<li>config kubectl binary : </li>
</ul>

<pre><code>kubectl config set-cluster test-legacy-2 --server=https://192.168.x.y:4443 --certificate-authority=/somelocation/ca.pem
</code></pre>

<pre><code>kubectl config set-credentials USER@mydomain.com --auth-provider=azure --auth-provider-arg=environment=AzurePublicCloud --auth-provider-arg=client-id=xyz456 --auth-provider-arg=tenant-id=OurAADTenantID --auth-provider-arg=apiserver-id=abc123
</code></pre>

<p>Also in the Azure client app manifest, had to specify :</p>

<p><code>"allowPublicClient":true,</code></p>

<p><code>"oauth2AllowIdTokenImplicitFlow":true</code></p>

<p>Otherwise had error "<em>Failed to acquire a token: acquiring a new fresh token: waiting for device code authentication to complete: autorest/adal/devicetoken: Error while retrieving OAuth token: Unknown Error"</em>.
Found on <a href="https://github.com/MicrosoftDocs/azure-docs/issues/10326" rel="nofollow noreferrer">https://github.com/MicrosoftDocs/azure-docs/issues/10326</a></p>

<p>Issues start when trying to filter on some security group that I find in the JWT as per <a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens" rel="nofollow noreferrer">https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens</a></p>

<p>I am receiving a format error even though the JWT Azure sends me does contain the groups in the right format (json array of strings)</p>

<p>Config :</p>

<ul>
<li>In azure web app manifest to have the groups in my JWT : </li>
</ul>

<p><code>"groupMembershipClaims": "SecurityGroup",</code></p>

<ul>
<li>kube api server yaml manifest :</li>
</ul>

<p><code>- --oidc-groups-claim=groups</code></p>

<p><code>- --oidc-required-claim=groups=bbc2eedf-79cd-4505-9fb4-39856ed3790e</code></p>

<p>with the string here being the GUID of my target security group.</p>

<p>I am receiving <code>error: You must be logged in to the server (Unauthorized)</code> on output of kubectl and the kube api server logs provide me this <code>authentication.go:62] Unable to authenticate the request due to an error: [invalid bearer token, [invalid bearer token, oidc: parse claim groups: json: cannot unmarshal array into Go value of type string]]</code></p>

<p>But I don't understand why it is not happy cause when I decode the JWT I do have</p>

<pre><code>"groups": [
    "00530f35-0013-4237-8947-6e3f6a7895ca",
    "bbc2eedf-79cd-4505-9fb4-39856ed3790e",
    "17dff614-fd68-4a38-906c-69561daec8b7"
  ],
</code></pre>

<p>which to my knowledge is a well-formatted json array of strings...</p>

<p>Why does the api server complain about the JWT ?</p>

GuiFP
<p><a href="https://github.com/kubernetes/kubernetes/blob/27cf50d85edb91357d56fd762271974e7a7254bc/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go#L620-L634" rel="nofollow noreferrer">Ok so, Required claims must be a string, not an array of strings</a></p>

<p>But I found a workaround.</p>

<ul>
<li>Don't use oidc-groups-claim and oidc-required-claim</li>
<li>In Azure, go to the Properties of the API server App.</li>
<li>Select Yes in "User assignment required"</li>
<li>In "Users and groups" add the specific Security Group you want to filter on</li>
<li>To test : Remove yourself from the Security Group</li>
<li>Wait for the token to expire (in my case it was 1 hour)</li>
<li>You can't log in anymore</li>
</ul>
