For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Azure backend authentication
Authenticate to an Azure service from the gateway with a Microsoft Entra ID token.
About
The azure backend authentication method gets a Microsoft Entra ID token and writes it to the Authorization header of every request that the gateway forwards to the backend. The gateway requests the token for the Azure Cognitive Services scope, or for the Azure AI scope when the backend is an Azure AI Foundry endpoint, and it caches the credential after the first successful use.
The method has two forms.
- Implicit. You set
azure: {}and configure no credential source. The gateway detects the identity from its own environment. This is the recommended form on AKS, where the workload identity of the pod supplies the token and no secret is stored in the cluster. - Explicit. You name one credential source: a Secret that holds service principal credentials, a managed identity, or a workload identity. Use an explicit source when the gateway must use an identity other than the one that the environment would give it.
At most one credential source may be set. The API server rejects a policy that sets two.
Before you begin
Follow the Get started guide to install agentgateway.
Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.
Get the external address of the gateway and save it in an environment variable.
Tip
Kind cluster? Kind does not support
LoadBalancerservices by default. To use this option with a Kind cluster, install and runcloud-provider-kind.export INGRESS_GW_ADDRESS=$(kubectl get svc -n agentgateway-system agentgateway-proxy -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
You also need an Azure resource to authenticate to, and an identity that is allowed to call it.
Choose a credential source
Review the following example configuration. Each tab shows the auth block of an AgentgatewayPolicy that targets an AgentgatewayBackend.
Leave azure empty, and the gateway detects the identity from its environment. On AKS with workload identity enabled, this is the form to use.
auth:
azure: {}| Field | Description |
|---|---|
azure | Set to {} to detect the credential from the environment. Set exactly one child field to name a credential source instead. |
azure.secretRef | Secret in the policy namespace that holds service principal credentials under the clientID, tenantID, and clientSecret keys. |
azure.workloadIdentity | Set to {} to use the federated token and the Azure environment variables that are projected into the gateway pod. |
azure.managedIdentity | Names a user-assigned managed identity. |
Warning
The managedIdentity field requires all three of clientId, objectId, and resourceId, but the gateway uses only the first one that is not empty, in that order. A policy that names one identifier is rejected with objectId: Required value. To use a user-assigned managed identity, set clientId to the identifier that you want the gateway to use, and set the other two fields to a placeholder. Prefer workloadIdentity or the implicit form where you can, because neither has this restriction.
Configure Azure backend authentication
Create a Secret with your service principal credentials in it. Skip this step if you use the implicit form, workload identity, or a managed identity.
kubectl create secret generic azure-creds \ --namespace httpbin \ --from-literal=clientID="<your-client-id>" \ --from-literal=tenantID="<your-tenant-id>" \ --from-literal=clientSecret="<your-client-secret>"Create an AgentgatewayPolicy that attaches Azure authentication to your Azure backend.
kubectl apply -f- <<EOF apiVersion: agentgateway.dev/v1alpha1 kind: AgentgatewayPolicy metadata: name: azure-backend-auth namespace: httpbin spec: targetRefs: - group: agentgateway.dev kind: AgentgatewayBackend name: my-azure-backend backend: auth: azure: secretRef: name: azure-creds EOFVerify that the controller accepted the policy.
kubectl get AgentgatewayPolicy azure-backend-auth -n httpbin \ -o jsonpath='{.status.ancestors[0].conditions[?(@.type=="Accepted")].message}'Example output:
Policy acceptedSend a request through the gateway to your Azure backend. A
200response means that the gateway got a token and that Azure accepted it.
How the gateway resolves an implicit credential
When you set azure: {}, the gateway tries the following credential sources in order and stops at the first one that returns a token. The chain matches the DefaultAzureCredential chain of the Azure SDK.
- Environment credential. A service principal, used when
AZURE_TENANT_ID,AZURE_CLIENT_ID, andAZURE_CLIENT_SECRETare all set. - Workload identity credential. A federated token, used when
AZURE_FEDERATED_TOKEN_FILE,AZURE_TENANT_ID, andAZURE_CLIENT_IDare set. This is the source that an AKS cluster with workload identity enabled supplies. - Managed identity credential. The identity of the Azure host, read from the instance metadata service. A user-assigned identity is selected with
AZURE_CLIENT_ID. - Developer tools credential. The cached login of the Azure CLI (
az login) or the Azure Developer CLI (azd auth login).
The gateway caches the source that first returns a token and uses it for every later request.
Two behaviors of this chain are worth knowing.
- The managed identity step is guarded by a probe. Before it tries the instance metadata service, the gateway opens a TCP connection to
169.254.169.254:80and waits one second. If the connection does not succeed, the gateway skips the step. Without the probe, the Azure SDK retries for about 99 seconds on a host that is not an Azure virtual machine, which would stall every request on the route. The gateway skips the probe whenIDENTITY_ENDPOINTorMSI_ENDPOINTis set, because the SDK then uses that endpoint instead of the metadata service. - The developer tools step calls a command that the gateway image does not contain. A gateway that runs in Kubernetes cannot reach step 4, because neither
aznorazdis installed in the image. Treat the step as available for local development with the standalone binary only.
Tip
To find out which source the gateway used, set the log level to trace and look for DefaultAzureCredential in the gateway logs. The gateway records the name of the source that provided the token, and the construction error of every source that failed.
Troubleshoot
A request that the gateway cannot authenticate returns a 500.
backend authentication failed: the credential provider was not enabled| Symptom | Cause |
|---|---|
The API server rejects the policy with objectId: Required value. | The managedIdentity field names one identifier. All three fields are required. See the warning earlier on this page. |
The API server rejects the policy with at most one of the fields in [secretRef managedIdentity workloadIdentity] may be set. | The policy names two credential sources. Name one, or set azure: {} to detect the source. |
The API server rejects the policy with unknown field "spec.backend.auth.azure.explicitConfig". | The configuration was copied from the standalone binary, which nests the credential source under explicitConfig. In Kubernetes, set the source directly on azure. |
Every request returns a 500, and the gateway logs show that each credential source failed to construct. | The gateway has no identity. Confirm that workload identity is enabled on the cluster and that the service account of the gateway is annotated for it, or supply a Secret with secretRef. |
| The first request on a route takes several seconds. | The gateway is resolving the credential for the first time. The result is cached, so later requests do not pay this cost. |
Cleanup
You can remove the resources that you created in this guide.kubectl delete AgentgatewayPolicy azure-backend-auth -n httpbin
kubectl delete secret azure-creds -n httpbin