Ga-M
Ga-M

Reputation: 11

Issues generating IMDS access token from AKS Pod using workload identity

I'm having some issues when generating an access token from within a pod in AKS with workload identity enabled.

I created the AKS cluster, the user-assigned managed identity, granted a Contributor role to the whole subscription to it, created a federated identity, and also created the service account using Kubectl and deployed a testing pod.

export RESOURCE_GROUP="my-test"; export LOCATION="eastus2"; export CLUSTER_NAME="my-test-cluster"; export SERVICE_ACCOUNT_NAMESPACE="default"; export SERVICE_ACCOUNT_NAME="workload-identity-sa"; export SUBSCRIPTION="$(az account show --query id --output tsv)"; export USER_ASSIGNED_IDENTITY_NAME="my-identity"; export FEDERATED_IDENTITY_CREDENTIAL_NAME="my-federated-identity"
az aks create -g "${RESOURCE_GROUP}" -n "${CLUSTER_NAME}" --enable-oidc-issuer --enable-workload-identity --generate-ssh-keys
export AKS_OIDC_ISSUER="$(az aks show -n "${CLUSTER_NAME}" -g "${RESOURCE_GROUP}" --query "oidcIssuerProfile.issuerUrl" -o tsv)"
az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --subscription "${SUBSCRIPTION}"
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -o tsv)"
az role assignment create --assignee "${USER_ASSIGNED_CLIENT_ID}" --role "Contributor" --scope "/subscriptions/${SUBSCRIPTION}"
az identity federated-credential create --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} --identity-name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --issuer "${AKS_OIDC_ISSUER}" --subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}" --audience api://AzureADTokenExchange

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    azure.workload.identity/client-id: "${USER_ASSIGNED_CLIENT_ID}"
  name: "${SERVICE_ACCOUNT_NAME}"
  namespace: "${SERVICE_ACCOUNT_NAMESPACE}"
EOF

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: yourpod
  namespace: "${SERVICE_ACCOUNT_NAMESPACE}"
  labels:
    azure.workload.identity/use: "true"  # Required, only the pods with this label can use workload identity
spec:
  serviceAccountName: "${SERVICE_ACCOUNT_NAME}"
  containers:
    - image: mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11
      name: containername
      command: ["sleep"]
      args: ["infinity"]
EOF

Within the testing pod, I installed az cli and I was able to log in using the federated identity and list some resources successfully:

az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal --username "${AZURE_CLIENT_ID}" --tenant "${AZURE_TENANT_ID}"
az group list
az logout

But I'm having a hard time whenever I try to call some Azure REST API using IMDS' access token.

From a VM (with the proper access configured to Azure resources of course), I could request the access token by hitting IMDS, then calling some API:

access_token=$(curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2023-07-01&resource=https%3A%2F%2Fmanagement.azure.com' -H Metadata:true | grep -Po '"access_token": *\K"[^"]*"' | sed 's/"//g')
curl https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups?api-version=2023-07-01 -H "Authorization: Bearer $access_token"

How to achieve this from a pod? Using the federated token file doesn't work, like: access_token="$(cat /var/run/secrets/azure/tokens/azure-identity-token)"

There is something else related to it. If I grant some permissions to the agentpool managed identity, I can request the access token using the metadata service (169.254.169.254) above and call that REST API and everything will work, regardless if I'm running with from the VMSS shell terminal or inside a pod. Is there any way to prevent the pod from assuming the agent pool identity?

The idea is to have the agent pool managed identity configured with some permissions but not let the pods to access the resources the VMSS instances can access, but at the same time, to have a second managed identity with access to some other resources where the pods will use to access them.

Upvotes: 0

Views: 1015

Answers (1)

sneale
sneale

Reputation: 11

You need to use the federated token at /var/run/secrets/azure/tokens/azure-identity-token to request an access token. See https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow#third-case-access-token-request-with-a-federated-credential

Upvotes: 1

Related Questions