Skip to main content
Reducto can call every Azure service with one Entra ID workload identity instead of keys. Use it when your Azure policy disables key (local) authentication on storage accounts or Azure AI services, as many Azure Government tenants require. Each Reducto pod exchanges its Kubernetes service-account token for Entra ID tokens, and every Azure client in the pod shares that identity and its token cache.

What the identity covers

Normal blob uploads, downloads, and deletes still use AZURE_STORAGE_CONNECTION_STRING. See Azure Blob Storage authentication for a SAS connection string on an account with shared-key access disabled.

Set up the identity

  1. Create a user-assigned managed identity in your Entra tenant.
  2. Add a federated identity credential that trusts your cluster’s OIDC issuer. Set the subject to system:serviceaccount:<namespace>:<release>-reducto. Its audience must equal azureWorkloadIdentity.audience (default api://AzureADTokenExchange). If your tenant created the credential with another audience, set the chart value to match.
  3. Assign the roles in the table above for the services you use.
  4. Mount the federated token on the pods, with the AKS webhook or the chart’s azureWorkloadIdentity values. Follow Mount the federated token. With the webhook, label every Reducto component (http, worker, and every streaq worker pool). The chart fails the render when AZURE_AI_SERVICES_AUTH=workload_identity is set and a component has no identity.
  5. Allow outbound HTTPS from the pods to the Entra authority host (login.microsoftonline.us in Azure Government; the AzureActiveDirectory service tag). Token exchange has no private endpoint, also when your Azure services use private endpoints.
Helm values (explicit projection)
The chart sets AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_AUTHORITY_HOST, and AZURE_FEDERATED_TOKEN_FILE on every Reducto pod.

Azure AI services

AZURE_AI_SERVICES_AUTH controls Azure Vision OCR and Azure OpenAI together. It defaults to key. With workload_identity:
  • Remove AZURE_VISION_KEY, every key in AZURE_VISION_ARRAY, and AZURE_OPENAI_API_KEY. Reducto refuses to start with a key in this mode, so a leftover key cannot keep authenticating calls.
  • Use each resource’s custom subdomain as its endpoint, for example https://<resource-name>.cognitiveservices.azure.us/ or https://<resource-name>.openai.azure.us/. Entra ID authentication does not work with a regional endpoint.
  • Private endpoints work for the services. The custom subdomain resolves to the private IP address through your private DNS zone. Token exchange still needs outbound HTTPS to the Entra authority host.
Reducto checks this configuration in two places:
  • helm template and helm upgrade fail, and name the component, when AZURE_AI_SERVICES_AUTH=workload_identity is set and a component has no workload identity.
  • A pod fails to start when AZURE_VISION_KEY, AZURE_OPENAI_API_KEY, or a key in AZURE_VISION_ARRAY is still set in this mode.
Pods that call no Azure AI service, such as the inference pod, start without the identity. So a deployment outside the Helm chart that sets the mode with no identity starts, and its first OCR or Azure OpenAI call fails with an error that names the missing variables.

Azure Government and other clouds

Reducto takes the cloud from AZURE_AUTHORITY_HOST, which the chart sets from azureWorkloadIdentity.authorityHost, and requests every Azure AI services token for that cloud’s audience. A custom domain or a gateway in front of a service therefore gets the right audience. With AZURE_AI_SERVICES_AUTH=workload_identity, an authority host of no known cloud fails the first OCR or Azure OpenAI call instead of sending a token for the wrong cloud. Blob Storage tokens use the storage account’s own host as the audience, which works in every cloud.

Troubleshooting

OCR or LLM calls fail with an authentication error and no retry. The identity is missing, its token file cannot be read, or Entra rejected the token exchange. Reducto does not retry it, because every attempt and every endpoint fails the same way. For OCR, the job fails at once with an internal error. For an LLM call, Reducto skips the Azure OpenAI model and tries your other configured models; if every model fails this way, the job fails with an internal error that names the identity. Check the token mount (/var/run/secrets/azure/tokens/azure-identity-token), the federated credential’s issuer and subject, and the role assignments. Azure returns 401 with a valid token. The token audience does not match the resource’s cloud, or the endpoint is a regional endpoint. Check azureWorkloadIdentity.authorityHost, and use the custom subdomain of the resource. Calls time out getting a token. The pods cannot reach the Entra authority host. Allow outbound HTTPS to it. Each token attempt waits at most 5 seconds to connect and 10 seconds to read, with one retry, so a page fails within about 30 seconds instead of hanging. Azure returns 403. The identity lacks the role on that resource. Role assignments can take several minutes to apply.

Roll back

Set AZURE_AI_SERVICES_AUTH=key and restore the keys, then restart the pods. A Reducto release older than the one that added AZURE_AI_SERVICES_AUTH ignores the setting and needs the keys, so restore the keys before you roll back the release. During an upgrade, disable key authentication on your Azure resources only after every Reducto pod runs the new release. Blob Storage signing switches back to account-key signing when you restore AccountKey in the connection string or AZURE_STORAGE_ACCOUNT_KEY.