Skip to content

feat: add Azure Managed Identity token provider support (revival of #1183)#2378

Open
Sarthak160 wants to merge 4 commits into
envoyproxy:mainfrom
Sarthak160:feat/azure-managed-identity-token-provider
Open

feat: add Azure Managed Identity token provider support (revival of #1183)#2378
Sarthak160 wants to merge 4 commits into
envoyproxy:mainfrom
Sarthak160:feat/azure-managed-identity-token-provider

Conversation

@Sarthak160

@Sarthak160 Sarthak160 commented Jul 16, 2026

Copy link
Copy Markdown

Description

This PR adds Azure Managed Identity support to BackendSecurityPolicy, so Azure OpenAI backends can be accessed with a managed identity available to the Envoy AI Gateway controller — no client secret to provision or rotate:

spec:
  type: AzureCredentials
  azureCredentials:
    # system-assigned managed identity / Azure Workload Identity / default credential chain
    managedIdentity: {}
    # OR a user-assigned managed identity selected by client ID
    # managedIdentity:
    #   clientID: <uami-client-id>

How it works:

  • A new azureManagedIdentityTokenProvider in internal/controller/tokenprovider obtains Azure access tokens using the identity in the controller's environment:
    • managedIdentity: {} (no client ID) uses azidentity.DefaultAzureCredential, which resolves Azure Workload Identity (federated service account tokens injected on AKS), the system-assigned managed identity via IMDS, environment variables, and Azure CLI credentials for local development.
    • managedIdentity.clientID selects a user-assigned managed identity, preferring WorkloadIdentityCredential when the federated token environment is present and falling back to IMDS-based ManagedIdentityCredential (chained), so it works both with AKS Workload Identity and with identities attached to the cluster VMs.
  • The token flows through the existing AzureTokenRotator machinery unchanged: the controller rotates the token into the generated secret, and the data plane picks it up exactly like the client-secret and OIDC flows. No extproc/filterapi changes.
  • API/CRD: azureCredentials.managedIdentity is added to both v1alpha1 and v1beta1; clientID/tenantID become optional, with CEL validation requiring exactly one of clientSecretRef / oidcExchangeToken / managedIdentity, and requiring clientID+tenantID for the two existing methods while forbidding them for managedIdentity (they are unused there). Existing resources are unaffected.
  • Also updates the AI_GATEWAY_AZURE_PROXY_URL proxy support to apply to the new credential types, adds an example manifest (examples/basic/azure_openai_managed_identity.yaml), CEL validation tests, controller tests, and provider unit tests.

Related Issues/PRs (if applicable)

Fixes #1180
Related PR: #1183

This revives and continues @MattMencel's #1183 (closed unmerged after he moved to another solution), per @mathetake's "feel free to reopen!". Since the codebase has moved on by ~10 months (the API now exists in both v1alpha1 and v1beta1, and new credential types were added), this is a fresh port of that design onto current main rather than a rebase. Matt is credited as co-author on the commit.

What changed compared to #1183:

  • API shape: instead of a useManagedIdentity: bool flag with an overloaded top-level clientID, this uses a managedIdentity sub-struct (with an optional clientID for user-assigned identities), following the same pattern as gcpCredentials.workloadIdentityFederationConfig. This also removes the wart in feat: add Azure Managed Identity token provider support #1183 where tenantID remained required-but-unused for managed identity.
  • User-assigned identities now also work with AKS Workload Identity (workload identity credential with client-ID override, chained with IMDS), not only IMDS.
  • Applied to both v1alpha1 and v1beta1 and to the current CRD/codegen/apidoc layout.
  • Dropped from feat: add Azure Managed Identity token provider support #1183: .gitignore/.codespell.ignorewords edits and the merge commit.

Special notes for reviewers (if applicable)

On the e2e validation gap that stalled #1183: we (Alpheya) run Envoy Gateway and AI workloads on AKS with Azure Workload Identity in production-like environments, and we can validate this end-to-end there — this was the missing piece last time. Concretely, we can run: an AKS cluster with workload identity enabled, the AI Gateway controller's service account federated to a managed identity (and separately, a user-assigned identity attached to the node pool), a BackendSecurityPolicy with managedIdentity targeting an Azure OpenAI/Cognitive Services backend, and chat-completion traffic through the gateway verifying token acquisition, rotation into the generated secret, and authenticated upstream calls. The pod → federated service account → managed identity token → Azure Cognitive Services call path is already proven in our clusters. Happy to run any additional scenarios the maintainers want before merge, and to keep validating this path for future regressions.

What was run locally (macOS, Go toolchain per repo):

  • make precommit — pass (tidy, spellcheck, apigen, codegen, apidoc, format, lint, editorconfig, helm-test; golangci-lint 0 issues)
  • make test — pass (full unit suite)
  • make test-crdcel — pass (envtest CEL validation, including the new managed-identity cases)

Not run locally: make test-e2e / AKS end-to-end (that's exactly the validation we're offering to do on our clusters, and can report results on this PR).

Per the repo's generative AI policy: this PR was developed with AI assistance; the changes have been fully reviewed and are owned/understood by the submitter, who will address review feedback. DCO is signed on the commit.

Adds a managedIdentity authentication option to azureCredentials in
BackendSecurityPolicy so that Azure OpenAI backends can be accessed with
an Azure managed identity available to the Envoy AI Gateway controller
(system-assigned, user-assigned by client ID, or Azure Workload Identity
on AKS), without provisioning a client secret.

The acquired token is rotated through the existing AzureTokenRotator
machinery, so no data plane changes are needed.

This continues the work started by Matt Mencel in envoyproxy#1183.

Co-authored-by: Matt Mencel <matt@techminer.net>
Signed-off-by: Sarthak Shyngle <sarthak.shyngle@alpheya.com>
@Sarthak160
Sarthak160 force-pushed the feat/azure-managed-identity-token-provider branch from d507532 to a9a3b7b Compare July 16, 2026 07:45
Signed-off-by: Sarthak Shyngle <sarthak.shyngle@alpheya.com>
@Sarthak160
Sarthak160 force-pushed the feat/azure-managed-identity-token-provider branch from 6489f0a to 8ea2fdd Compare July 16, 2026 19:24
@Sarthak160
Sarthak160 marked this pull request as ready for review July 17, 2026 05:44
@Sarthak160
Sarthak160 requested a review from a team as a code owner July 17, 2026 05:44
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 17, 2026
@Sarthak160

Copy link
Copy Markdown
Author

Follow-up: full controller-on-cluster validation now complete (extends the token-provider validation above).

We've now deployed the controller built from this branch onto our AKS cluster (GitOps/Flux, dedicated namespace, controller SA federated to a user-assigned managed identity via Azure Workload Identity) with a real BackendSecurityPolicy:

type: AzureCredentials
azureCredentials:
  managedIdentity:
    clientID: <uami-client-id>

Observed, end to end:

  1. The BSP reconciler selected the managed-identity path and minted a 24h Entra token keylessly — controller log: credentials has not yet expired for azure-openai-credentials … of auth type AzureCredentials, renewing in 1433 minutes (i.e. rotation scheduled ~5min before expiry, as designed).
  2. The existing AzureTokenRotator machinery materialized the token into the generated secret (ai-eg-bsp-…-credentials, key azureAccessToken) — no code changes to the rotator/data-plane path, as intended by the PR.
  3. The controller-minted token (extracted from the rotated secret) authorized a live Azure OpenAI chat/completions call from in-cluster: HTTP 200, completion id chatcmpl-E2dSd…, model gpt-5.4-nano-… (the resource is local_auth_enabled=false, so bearer-token-only).
  4. The controller also reconciled the AIServiceBackend/AIGatewayRoute and generated the HTTPRoute without issues.

Incidental but reassuring: the same token was rejected (403, network ACL) when replayed from outside the cluster's egress — the minted tokens are useless off the allow-listed network.

That covers both validation layers we promised on #1180: token provider (previous comment) and the controller/rotator loop on a real AKS + Workload Identity environment. Happy to run anything else the maintainers want.

@Sarthak160

Copy link
Copy Markdown
Author

Gentle ping @mathetake — would appreciate a first pass on this when you have a moment.

Since opening, both validation layers are done on a live AKS cluster (details in the two comments above): the token provider itself (system-assigned and user-assigned paths, real Azure OpenAI inference 200s), and the full controller + rotator flow on-cluster (BSP-minted tokens via workload identity, rotated into the backend secret, serving live traffic through the gateway).

This picks up where #1183 left off — we're effectively the e2e validation environment that PR was waiting on — and would close #1180. Happy to adjust the shape of the provider if you'd prefer a different direction.

@missBerg missBerg added enhancement New feature or request area/api Control plane API (CRDs) area/controller Controller and reconciliation labels Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api Control plane API (CRDs) area/controller Controller and reconciliation enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for managed identity for Azure OpenAI and AKS clusters

2 participants