-
Notifications
You must be signed in to change notification settings - Fork 86
LCORE-1518: Skip model authentication against Azure #1766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,6 @@ set -e | |
| INPUT_CONFIG="${LLAMA_STACK_CONFIG:-/opt/app-root/run.yaml}" | ||
| ENRICHED_CONFIG="/opt/app-root/run.yaml" | ||
| LIGHTSPEED_CONFIG="${LIGHTSPEED_CONFIG:-/opt/app-root/lightspeed-stack.yaml}" | ||
| ENV_FILE="/opt/app-root/.env" | ||
|
|
||
| # Enrich config if lightspeed config exists | ||
| if [ -f "$LIGHTSPEED_CONFIG" ]; then | ||
|
|
@@ -16,14 +15,7 @@ if [ -f "$LIGHTSPEED_CONFIG" ]; then | |
| python3 /opt/app-root/llama_stack_configuration.py \ | ||
| -c "$LIGHTSPEED_CONFIG" \ | ||
| -i "$INPUT_CONFIG" \ | ||
| -o "$ENRICHED_CONFIG" \ | ||
| -e "$ENV_FILE" 2>&1 || ENRICHMENT_FAILED=1 | ||
|
|
||
| # Source .env if generated (contains AZURE_API_KEY) | ||
| if [ -f "$ENV_FILE" ]; then | ||
| # shellcheck source=/dev/null | ||
| set -a && . "$ENV_FILE" && set +a | ||
| fi | ||
| -o "$ENRICHED_CONFIG" 2>&1 || ENRICHMENT_FAILED=1 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The API key is not passed by |
||
|
|
||
| if [ -f "$ENRICHED_CONFIG" ] && [ "$ENRICHMENT_FAILED" -eq 0 ]; then | ||
| echo "Using enriched config: $ENRICHED_CONFIG" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,15 +77,6 @@ async def lifespan(_app: FastAPI) -> AsyncIterator[None]: | |
|
|
||
| initialize_sentry() | ||
|
|
||
| azure_config = configuration.configuration.azure_entra_id | ||
| if azure_config is not None: | ||
| AzureEntraIDManager().set_config(azure_config) | ||
| if not AzureEntraIDManager().refresh_token(): | ||
| logger.warning( | ||
| "Failed to refresh Azure token at startup. " | ||
| "Token refresh will be retried on next Azure request." | ||
| ) | ||
|
|
||
| llama_stack_config = configuration.configuration.llama_stack | ||
| await AsyncLlamaStackClientHolder().load(llama_stack_config) | ||
| client = AsyncLlamaStackClientHolder().get_client() | ||
|
|
@@ -104,6 +95,11 @@ async def lifespan(_app: FastAPI) -> AsyncIterator[None]: | |
| ) | ||
| raise | ||
|
|
||
| azure_entra_id_config = configuration.configuration.azure_entra_id | ||
| if azure_entra_id_config is not None: | ||
| AzureEntraIDManager().set_config(azure_entra_id_config) | ||
| azure_base_url = await AsyncLlamaStackClientHolder().get_azure_base_url() | ||
| AzureEntraIDManager().set_base_url(azure_base_url) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In FastAPI lifespan just setup manager's attributes and defer the token acquisition to inference requests. |
||
| logger.info("Registering MCP servers") | ||
| await register_mcp_servers_async(logger, configuration.configuration) | ||
| logger.info("App startup complete") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,5 @@ | ||
| """Azure Entra ID token manager for Azure OpenAI authentication.""" | ||
|
|
||
| import os | ||
| import time | ||
| from typing import Optional | ||
|
|
||
|
|
@@ -34,7 +33,13 @@ class AzureEntraIDManager(metaclass=Singleton): | |
| def __init__(self) -> None: | ||
| """Initialize the token manager with empty state.""" | ||
| self._expires_on: int = 0 | ||
| self._access_token: SecretStr = SecretStr("") | ||
| self._entra_id_config: Optional[AzureEntraIdConfiguration] = None | ||
| self._azure_base_url: Optional[str] = None | ||
|
|
||
| def set_base_url(self, base_url: Optional[str]) -> None: | ||
| """Set the Azure API base.""" | ||
| self._azure_base_url = base_url | ||
|
|
||
| def set_config(self, azure_config: AzureEntraIdConfiguration) -> None: | ||
| """Set the Azure Entra ID configuration.""" | ||
|
|
@@ -53,8 +58,24 @@ def is_token_expired(self) -> bool: | |
|
|
||
| @property | ||
| def access_token(self) -> SecretStr: | ||
| """Return the access token from environment variable as SecretStr.""" | ||
| return SecretStr(os.environ.get("AZURE_API_KEY", "")) | ||
| """Return the cached access token.""" | ||
| return self._access_token | ||
|
|
||
| @property | ||
| def azure_base_url(self) -> Optional[str]: | ||
| """Return the cached Azure API base.""" | ||
| return self._azure_base_url | ||
|
|
||
| def build_azure_provider_data(self) -> Optional[dict[str, str]]: | ||
| """Build azure_api_key and azure_base_url entries for provider data. | ||
|
|
||
| Returns: | ||
| Provider data dict when a token and base_url are available. | ||
| """ | ||
| token = self.access_token.get_secret_value() | ||
| if not token or self.azure_base_url is None: | ||
| return None | ||
| return {"azure_api_key": token, "azure_api_base": self.azure_base_url} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Config and validator attribute discrepancy in LLS ( |
||
|
|
||
| def refresh_token(self) -> bool: | ||
| """Refresh the cached Azure access token. | ||
|
|
@@ -76,9 +97,9 @@ def refresh_token(self) -> bool: | |
| return False | ||
|
|
||
| def _update_access_token(self, token: str, expires_on: int) -> None: | ||
| """Update the token in env var and track expiration time.""" | ||
| """Update the cached token and track expiration time.""" | ||
| self._access_token = SecretStr(token) | ||
| self._expires_on = expires_on - TOKEN_EXPIRATION_LEEWAY | ||
| os.environ["AZURE_API_KEY"] = token | ||
| expiry_time = time.strftime( | ||
| "%Y-%m-%d %H:%M:%S", time.localtime(self._expires_on) | ||
| ) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change in attribute name