Azure/kubelogin

Get JWT token from AzureAD v2.0 endpoint

sleterrier opened this issue · 7 comments

Hello,

Is it possible to instruct azure-kubelogin to obtain a JWT token from https://login.microsoftonline.us/tenant-id/v2.0 instead of https://sts.windows.net/tenant-id?

Context

  • kube-apiserver configured with:
      --oidc-username-claim=preferred_username \
      --oidc-client-id=aad-app-id \
      --oidc-issuer-url=https://login.microsoftonline.us/tenant-id/v2.0
    
  • Appropriate RoleBindings based on AAD group memberships, known to be functional (from a few years of configuring our kube-apiservers against v1.0 endpoint).
  • azure-kubelogin v0.0.30.
  • kubectl context based on Setup k8s OIDC Provider using Azure AD docs.

Issue

All kubectl commands fail with error: You must be logged in to the server (Unauthorized) when kube-apiserver is configured with v2.0 endpoint as oidc-issuer.

Suspected root cause

azuread-kubelogin gets its token from the v1.0 endpoint, which mints JWT tokens with different claims than the v2.0 endpoint.

  • unique_name and upnonly present in tokens obtained from https://sts.windows.net/tenant-id (v1.0 endpoint):
    {
      "aud": "app-id",
      "iss": "https://sts.windows.net/tenant-id/",
      "groups": [
        "list",
        "of",
        "groups"
      ],
      "unique_name": "jdoe@example.com",
      "upn": "jdoe@example.com",
      "ver": "1.0"
    }
    
  • preferred_username and email only present in tokens obtained from https://login.microsoftonline.us/tenant-id/v2.0 (v2.0 endpoint):
    {
      "aud": "app-id",
      "iss": "https://login.microsoftonline.us/tenant-id/v2.0",
      "email": "jdoe@example.com",
      "groups": [
        "list",
        "of",
        "groups"
      ],
      "preferred_username": "jdoe@example.com",
      "ver": "2.0"
    }
    
bcho commented

Just to confirm, are you using device code authentication in this case?

That is correct. Using distinct --server-id and client-id if that also matters (with clientApp granted user_impersonation permission on serverApp).

bcho commented

I guess the culprit is kube-login is using adal SDK here:

emptyToken := adal.Token{}
client := &autorest.Client{}
deviceCode, err := adal.InitiateDeviceAuth(client, p.oAuthConfig, p.clientID, p.resourceID)
if err != nil {
return emptyToken, fmt.Errorf("initialing the device code authentication: %s", err)
}

We might need to update the SDK to make it support the v2 endpoint. But not sure the back compatibility here. Will discuss more with my team mate on this.

Thank you for looking into this @bcho, much appreciated ❤️

@sleterrier did you try -l interactive?

@weinong I had not, but confirm it allows azure-kubelogin to get tokens from the v2 endpoint! Thank you 🎉

Here are some details others might find useful:

  • kubelogin get-token \
    --environment AzureUSGovernmentCloud \
    --server-id <server-app-id> \
    --client-id <client-app-id> \
    --tenant-id <tenant-id> \
    --login interactive
    
  • Despite successful in-browser authentication, my initial attempts were failing with:

    Error: failed to get token: expected an empty error but received: InteractiveBrowserCredential authentication failed
    POST https://login.microsoftonline.us/<tenant-id>/oauth2/v2.0/token
    --------------------------------------------------------------------------------
    RESPONSE 401 Unauthorized
    --------------------------------------------------------------------------------
    {
      "error": "invalid_client",
      "error_description": "AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.",
      "error_codes": [
        7000218
      ],
      "timestamp": "2023-08-29 02:59:54Z",
      "trace_id": "obfuscated",
      "correlation_id": "obfuscated",
      "error_uri": "https://login.microsoftonline.us/error?code=7000218",
      "claims": "{\"access_token\":{\"capolids\":{\"essential\":true,\"values\":[\"obfuscated\"]}}}"
    
  • Which was due to an incorrect platform configuration on <client-app-id>. See MicrosoftDocs/azure-docs#61446 for details, TLDR: Mobile and Desktop applications is needed, not Web.

@sleterrier You are good now, right? please reopen for follow up