Azure Authentication Flow
This document explains the authentication flow from control plane pods to Azure APIs for managed Azure HostedClusters.
For CSI-based credential mounting details, see Secrets CSI Usage.
Authentication Overview
Managed Azure HostedClusters use certificate-based authentication with credentials stored in Azure Key Vault:
| Aspect | Description |
|---|---|
| Credential Type | X.509 Certificate |
| Credential Source | Azure Key Vault |
| Credential Delivery | Secrets Store CSI Driver |
| Azure SDK Library | msi-dataplane |
| Credential Rotation | Automatic via Key Vault |
Authentication Flow
Pod Startup → CSI Driver → Azure Key Vault → Credential File
↓
Azure ARM API ← Access Token ← Azure AD ← Azure SDK reads file
- CSI Driver mounts credential from Azure Key Vault (see Secrets CSI Usage)
- Credential File contains
UserAssignedIdentityCredentialsJSON with PEM certificate - Azure SDK uses
msi-dataplane.NewUserAssignedIdentityCredential()to load credentials - Azure AD validates the client certificate and issues an access token
- ARM API accepts the Bearer token for resource operations
Credential Loading Code
import "github.com/Azure/msi-dataplane/pkg/dataplane"
certPath := "/mnt/certs/" + credentialsSecretName
creds, err := dataplane.NewUserAssignedIdentityCredential(
ctx,
certPath,
dataplane.WithClientOpts(azcore.ClientOptions{Cloud: cloud.AzurePublic}),
)
// Use with Azure SDK clients
client, err := armresources.NewResourceGroupsClient(subscriptionID, creds, nil)
The credential automatically watches the file for changes and reloads when the CSI driver refreshes secrets.
Cloud Configuration File
{
"cloud": "AzurePublicCloud",
"tenantId": "<tenant-id>",
"subscriptionId": "<subscription-id>",
"resourceGroup": "<resource-group>",
"useManagedIdentityExtension": true,
"aadMSIDataPlaneIdentityPath": "/mnt/certs/<credential-secret-name>"
}
Credential Refresh
The msi-dataplane library handles credential refresh:
- File watcher monitors credential file for changes
- When CSI driver refreshes secrets, new credentials are loaded
- Backstop timer reloads every 6 hours
- Compares
notBeforetimestamps to detect newer credentials
Troubleshooting
Verify CSI Mount
kubectl exec -it <pod> -- ls -la /mnt/certs
kubectl exec -it <pod> -- cat /mnt/certs/<secret-name>
Check SecretProviderClass
kubectl get secretproviderclass -n <namespace>
kubectl describe secretproviderclasspodstatus -n <namespace>
Related Documentation
- Secrets CSI Usage - CSI driver overview