veerendra2
veerendra2

Reputation: 2273

Enforce kubeconfig token expiry for Entra ID enabled cluster AKS cluster

Recently I enabled Entra ID login for AKS cluster,

resource "azurerm_kubernetes_cluster" "this" {
...
  azure_active_directory_role_based_access_control {
    admin_group_object_ids = var.entraid_group_ids_cluster_admin
    azure_rbac_enabled     = false
    tenant_id              = var.tenant_id
  }
...

and installed kubelogin

az account set --subscription [REDACTED]
az aks get-credentials --resource-group [RG] --name [NAME]
kubelogin convert-kubeconfig -l azurecli

For the first time kubectl access after I enabled Entra ID, it asked for OTP and I can also see token in below path

$ ls  ~/.kube/cache/kubelogin/AzurePublicCloud-6dae42f8-4368-4678-94ff-3960e28e3630-80faf920-1908-4b52-b5ef-a8e7bedfc67a-97428d91-daa2-4245-a358-87ce5cc734f6.json
/Users/user.name/.kube/cache/kubelogin/AzurePublicCloud-6dae42f8-4368-4678-94ff-3960e28e3630-80faf920-1908-4b52-b5ef-a8e7bedfc67a-97428d91-daa2-4245-a358-87ce5cc734f6.json

I have been using kubectl access for a week, I see it never asked for OTP again (I think the token expiry time is 24 hours!?). If I look inside the cache token

$ cat ~/.kube/cache/kubelogin/AzurePublicCloud-6dae42f8-4368-4678-94ff-3960e28e3630-80faf920-1908-4b52-b5ef-a8e7bedfc67a-97428d91-daa2-4245-a358-87ce5cc734f6.json
{"access_token":"[REDACTED]","expires_in":4932,"expires_on":1727278105,"not_before":1727272872,"resource":"6dae42e8-4360-4679-94ef-3660e28f3630","token_type":"Bearer"}

The epoch time for "expires_on":1727278105 is Wednesday, 25 September 2024 15:28:25, the token is expired and isn't it should ask for OTP login again?

How to enforce expiry for kubeconfig token in this case? For example, after 24 hours, it should aks for OTP when I try to use kubectl

Upvotes: -1

Views: 188

Answers (2)

Joey Chen
Joey Chen

Reputation: 56

The answer to your question is: No.
Once access token is generated, it cannot be revoked unless it is expired.

However, if I am not wrong, the maximum of access token is 1 day (if kubelogin tried to set expiry time): https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes#configurable-token-lifetime-properties
So, let me start questioning where that "1 week" coming from.

A test to check the actual expire time:

joey [ ~ ]$ kubelogin get-token --server-id 6dae42f8-4368-4678-94ff-3960e28e3630 --client-id 80faf920-1908-4b52-b5ef-a8e7bedfc67a --tenant-id xxx-xxx-xxx-xxxx --login devicecode
{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"2025-02-13T16:57:01Z","token":"xxxxxxxx"}}
joey [ ~ ]$ date
Thu Feb 13 03:27:27 PM UTC 2025

Then I checked the cache file:

cat ~/.kube/cache/kubelogin/AzurePublicCloud-xxxx-xxx-xxx-xxxx.json 
{"access_token":"xxxxxxx","refresh_token":"xxxxxxx","expires_in":5377,"expires_on":1739465821,"not_before":1739460143,"resource":"6dae42f8-4368-4678-94ff-3960e28e3630","token_type":"Bearer"}

The expire_on value, 1739465821, is representing the date: 2025-02-13T16:57:01Z, same as in the first result.

This means kubelogin did not try to set custom expiry time. The result is around 60-90 minutes as default.

Maybe you want to do another test again to see if it is actually one week because I don't know the time you get the token.


Meantime, FYI:
If using azurecli as login method, there should not be cache file there.
Let me give you an example:

joey [ /home ]$ rm -r ~/.kube/cache/
joey [ /home ]$ kubelogin get-token --server-id 6dae42f8-4368-4678-94ff-3960e28e3630 --client-id 80faf920-1908-4b52-b5ef-a8e7bedfc67a --login azurecli -v 99
I0213 15:49:05.128663    3250 execCredentialPlugin.go:34] Login Method: azurecli, Environment: AzurePublicCloud, TenantID: , ServerID: 6dae42f8-4368-4678-94ff-3960e28e3630, ClientID: 80faf920-1908-4b52-b5ef-a8e7bedfc67a, IsLegacy: false, msiResourceID: , Timeout: 30s, tokenCacheDir: /home/joey/.kube/cache/kubelogin/, tokenCacheFile: /home/joey/.kube/cache/kubelogin/AzurePublicCloud-xxxxxxxxx-.json, AZURE_CONFIG_DIR: 
I0213 15:49:05.128773    3250 execCredentialPlugin.go:114] acquire new token
{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"2025-02-13T17:18:06Z","token":"xxxxxxxxx"}}
joey [ /home ]$ ls /home/joey/.kube/cache/kubelogin/
ls: cannot access '/home/joey/.kube/cache/kubelogin/': No such file or directory
joey [ /home ]$ kubelogin convert-kubeconfig -l azurecli -v 99
I0213 15:51:55.820362    3343 convert.go:187] Context: , Login Method: azurecli, Environment: AzurePublicCloud, TenantID: , ServerID: , ClientID: , IsLegacy: false, msiResourceID: , Timeout: 30s, tokenCacheDir: /home/joey/.kube/cache/kubelogin/, tokenCacheFile: /home/joey/.kube/cache/kubelogin/AzurePublicCloud---.json, AZURE_CONFIG_DIR: 
I0213 15:51:55.820444    3343 convert.go:197] Loading kubeconfig from /home/joey/.kube/config
I0213 15:51:55.821376    3343 loader.go:395] Config loaded from file:  /home/joey/.kube/config
I0213 15:51:55.821486    3343 convert.go:219] context: "clusterUser_aks-rbac-test_aks-rbac-test"
I0213 15:51:55.821517    3343 convert.go:226] converting...
I0213 15:51:55.821999    3343 loader.go:395] Config loaded from file:  /home/joey/.kube/config
I0213 15:51:55.822577    3343 loader.go:395] Config loaded from file:  /home/joey/.kube/config
joey [ /home ]$ ls /home/joey/.kube/cache/kubelogin/
ls: cannot access '/home/joey/.kube/cache/kubelogin/': No such file or directory

So in your question, you mentioned that you used kubelogin convert-kubeconfig -l azurecli. This is a very questionable context.

Upvotes: 0

Arko
Arko

Reputation: 3781

The expiration time for the kubectl token is determined by the Microsoft Entra ID configuration and cannot be modified. The token is cached and will only prompt for OTP again after it has expired or the K8s config file is re-created. The token lifetime is designed such that it cannot be less than 60 minutes. If you want to enforce a shorter token lifetime, you can use Privileged Identity Management to control access to your AKS cluster. By default, the Entra ID token has a 24-hour expiration time. You can use the kubelogin command kubelogin remove-tokens to remove the cached tokens. This will force to request a new token from Entra ID the next time it is used.

You can automate this using a cron job / script

crontab -e
0 0 * * * /usr/local/bin/kubelogin remove-tokens

This will run the remove-tokens command daily at midnight.

Checkout these MS docs for reference

Also please see these similar threads posted on MS QnA forum-

Upvotes: 0

Related Questions