Skip to content

Commit 5b6cf68

Browse files
committed
[aks-agent] Add Microsoft Entra ID authentication support for Azure OpenAI
This commit adds support for keyless authentication using Microsoft Entra ID (formerly Azure AD) for Azure OpenAI. Users can now skip providing an API key during initialization to enable workload identity-based authentication. Changes: - Bump version to 1.0.0b22 and aks-agent to v0.7.0 - Allow empty API key during Azure OpenAI configuration - Configure aks-agent pod to use workload identity with the same service account as aks-mcp - Add helm values: workloadIdentity.enabled=true, serviceAccount.create=false - Skip creating secrets and environment variables when API key is empty - Enable azureADTokenAuth flag in helm when API key is not provided
1 parent 2718c5d commit 5b6cf68

7 files changed

Lines changed: 40 additions & 9 deletions

File tree

src/aks-agent/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ To release a new version, please select a new version number (usually plus 1 to
1212
Pending
1313
+++++++
1414

15+
1.0.0b22
16+
++++++++
17+
* Feature: Add Microsoft Entra ID (formerly Azure AD) authentication support for Azure OpenAI
18+
1519
1.0.0b21
1620
++++++++
1721
* Bump aks-agent to v0.6.0

src/aks-agent/azext_aks_agent/_consts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
AKS_MCP_LABEL_SELECTOR = "app.kubernetes.io/name=aks-mcp"
5353

5454
# AKS Agent Version (shared by helm chart and docker image)
55-
AKS_AGENT_VERSION = "0.6.0"
55+
AKS_AGENT_VERSION = "0.7.0"
5656

5757
# Helm Configuration
5858
HELM_VERSION = "3.16.0"

src/aks-agent/azext_aks_agent/agent/k8s/aks_agent_manager.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,22 @@ def _create_helm_values(self):
927927
"create": False,
928928
}
929929

930+
# Configure aks-agent pod to use the same service account as aks-mcp for workload identity
931+
helm_values["workloadIdentity"] = {
932+
"enabled": True,
933+
}
934+
helm_values["serviceAccount"] = {
935+
"create": False,
936+
"name": self.aks_mcp_service_account_name,
937+
}
938+
939+
has_empty_api_key = any(
940+
not model_config.get("api_key") or not model_config.get("api_key").strip()
941+
for model_config in self.llm_config_manager.model_list.values()
942+
)
943+
if has_empty_api_key:
944+
helm_values["azureADTokenAuth"] = True
945+
930946
return helm_values
931947

932948
def save_llm_config(self, provider: LLMProvider, params: dict) -> None:

src/aks-agent/azext_aks_agent/agent/llm_config_manager.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ def get_env_vars(self, secret_name: str) -> List[Dict[str, str]]:
5050
"""
5151
env_vars_list = []
5252
for _, model_config in self.model_list.items():
53-
env_var = LLMProvider.to_env_vars(secret_name, model_config)
54-
env_vars_list.append(env_var)
53+
api_key = model_config.get("api_key")
54+
if api_key and api_key.strip():
55+
env_var = LLMProvider.to_env_vars(secret_name, model_config)
56+
env_vars_list.append(env_var)
5557
return env_vars_list
5658

5759

src/aks-agent/azext_aks_agent/agent/llm_providers/azure_provider.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ def parameter_schema(self):
4343
"api_key": {
4444
"secret": True,
4545
"default": None,
46-
"hint": None,
47-
"validator": non_empty
46+
"hint": "press enter to enable keyless authentication with Microsoft Entra ID",
47+
"validator": lambda v: True
4848
},
4949
"api_base": {
5050
"secret": False,
@@ -65,9 +65,12 @@ def validate_connection(self, params: dict) -> Tuple[str, str]:
6565
api_version = params.get("api_version")
6666
deployment_name = params.get("model")
6767

68-
if not all([api_key, api_base, api_version, deployment_name]):
68+
if not all([api_base, api_version, deployment_name]):
6969
return "Missing required Azure parameters.", "retry_input"
7070

71+
if not api_key or not api_key.strip():
72+
return None, "save"
73+
7174
# REST API reference: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/api-version-lifecycle?tabs=rest
7275
url = urljoin(api_base, f"openai/deployments/{deployment_name}/chat/completions")
7376

src/aks-agent/azext_aks_agent/agent/llm_providers/base.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ def to_k8s_secret_data(cls, params: dict):
175175
"""
176176
secret_key = cls.sanitize_k8s_secret_key(params)
177177
secret_value = params.get("api_key")
178+
if not secret_value or not secret_value.strip():
179+
return {}
178180
secret_data = {
179181
secret_key: base64.b64encode(secret_value.encode("utf-8")).decode("utf-8"),
180182
}
@@ -206,9 +208,13 @@ def to_secured_model_list_config(cls, params: dict) -> Dict[str, dict]:
206208
"""Create a model config dictionary for the model list from the provider parameters.
207209
Returns a copy of params with the api_key replaced by environment variable reference.
208210
"""
209-
secret_key = cls.sanitize_k8s_secret_key(params)
210211
secured_params = params.copy()
211-
secured_params.update({"api_key": f"{{{{ env.{secret_key} }}}}"})
212+
api_key = params.get("api_key")
213+
if api_key and api_key.strip():
214+
secret_key = cls.sanitize_k8s_secret_key(params)
215+
secured_params.update({"api_key": f"{{{{ env.{secret_key} }}}}"})
216+
else:
217+
secured_params.pop("api_key", None)
212218
return secured_params
213219

214220
@classmethod

src/aks-agent/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from setuptools import find_packages, setup
1111

12-
VERSION = "1.0.0b21"
12+
VERSION = "1.0.0b22"
1313

1414
CLASSIFIERS = [
1515
"Development Status :: 4 - Beta",

0 commit comments

Comments
 (0)