We are working on a project where an application running in Azure Kubernetes Service (AKS) needs to fetch CSV/XLS files from a specific SharePoint site. Currently, we're using an App Registration in Azure AD (Microsoft Entra ID) with a client ID and client secret to authenticate and access the SharePoint data via Microsoft Graph API. However, our security team is concerned about the risk of secrets being leaked or exposed.
However, our security team raised an issue that setting up the connection like that is not secure enough, and they would like us to consider alternatives where leaking the Client ID/Secret combination is not possible.
So, we’re looking for a more secure solution, preferably one that:
One solution that I think might work is to create a Managed Identity for the AKS pod that fetches the data from SharePoint, and give that Managed Identity the correct access on the Microsoft Graph API (on site level).
That way, all authentication and authorization is handled by Azure, and we don't have to manage Client ID and Client Secret combinations anymore.
You can use Azure Workload Identity for AKS with federated tokens instead of client secrets. Set up an OIDC-enabled AKS cluster, create a user-assigned managed identity, link it to a Kubernetes service account, and configure token volume projection. Your pod can then use this identity to securely obtain tokens and access SharePoint data via Microsoft Graph.
I tested this end-to-end approach in my environment successfully. Please find the workaround below:
Install > kubectl
az cli
and helm
Create an aks cluster with enabling workload identity along with oidc:
az aks create \
--resource-group anji-rg \
--name my-aks \
--enable-oidc-issuer \
--enable-workload-identity \
--node-count 1 \
--generate-ssh-keys
Configure the credentials to communicate with clusters:
az aks get-credentials --resource-group anji-rg --name my-aks
Then get the oidc issuer url: (you will need this later)
az aks show --resource-group anji-rg --name my-aks --query "oidcIssuerProfile.issuerUrl" -o tsv
Save this whenever we call this OIDC_ISSUERR it will be triggering the value:
OIDC_ISSUER=$(az aks show --resource-group anji-rg --name my-aks --query "oidcIssuerProfile.issuerUrl" -o tsv)
The OIDC URL looks like >
https://centralindia.oic.prod-aks.azure.com/xxxxxxxxxxx/xxxxxxxxxxxxxxxx/
Create a User-Assigned Managed Identity:
az identity create --name my-akspod-identity --resource-group anji-rg
Save these outputs to call these values:
CLIENT_ID=$(az identity show --name my-akspod-identity --resource-group anji-rg --query 'clientId' -o tsv)
IDENTITY_ID=$(az identity show --name my-akspod-identity --resource-group anji-rg --query 'id' -o tsv)
You can directly configure the federation credentials by going into portal > managed identity > your app (ex: in my case > my-akspod-identity) > federation credentials > add credentials > scenario> others issuer is your OIDC url > subject identifier > system:serviceaccount:spdemo:workload-sa > name it and save it.
Annotate Kubernetes Service Account to use Managed Identity: Create a name space:
kubectl create namespace spdemo
kubectl create serviceaccount workload-sa -n spdemo
Annotate the service account with the managed identity client ID:
kubectl annotate serviceaccount workload-sa \
--namespace spdemo \
azure.workload.identity/client-id=$CLIENT_ID
This pod uses a Kubernetes service account linked to an Azure Managed Identity and mounts a federated token.
The token allows Azure CLI in the container to authenticate securely with Microsoft Entra ID without secrets.
apiVersion: v1
kind: Pod
metadata:
name: graph-test
namespace: spdemo
spec:
serviceAccountName: workload-sa
automountServiceAccountToken: true
containers:
- name: test-container
image: mcr.microsoft.com/azure-cli
command: ["sleep"]
args: ["3600"]
volumeMounts:
- name: azure-identity-token
mountPath: /var/run/secrets/tokens
readOnly: true
volumes:
- name: azure-identity-token
projected:
sources:
- serviceAccountToken:
audience: api://AzureADTokenExchange
expirationSeconds: 3600
path: azure-identity-token
Apply it > kubectl apply -f pod.yaml
I have successfully logged into the pod and access the azure service
I am now able to log in to my pod, and it is up and running. I successfully communicated with Azure services from the pod. Let me know if you have any thoughts or doubts, and I will be glad to clear them. -Thank you. @Titulum