From 11f1beb47e0e700219fb0e71c046d602bd9be367 Mon Sep 17 00:00:00 2001 From: "Damian K. Kowalczyk" Date: Tue, 10 Feb 2026 23:07:39 -0800 Subject: [PATCH 1/2] Add Azure Managed Identity authentication support - Document Managed Identity and DefaultAzureCredential auth modes in model_repository.md with credential file examples - Add MI integration tests to L0_storage_azure/test.sh: system-assigned MI, user-assigned MI, DefaultAzureCredential, and invalid auth_type rejection - Tests gated behind TEST_AZURE_MANAGED_IDENTITY env var - Companion to core repo commit 4ef4ebaa (C++ implementation) --- docs/user_guide/model_repository.md | 53 ++++++++++++- qa/L0_storage_azure/test.sh | 116 +++++++++++++++++++++++++++- 2 files changed, 167 insertions(+), 2 deletions(-) diff --git a/docs/user_guide/model_repository.md b/docs/user_guide/model_repository.md index 21a1871e6e..837898838b 100644 --- a/docs/user_guide/model_repository.md +++ b/docs/user_guide/model_repository.md @@ -175,7 +175,9 @@ For a model repository residing in Azure Storage, the repository path must be pr $ tritonserver --model-repository=as://account_name/container_name/path/to/model/repository ... ``` -When using Azure Storage, you must set the `AZURE_STORAGE_ACCOUNT` and `AZURE_STORAGE_KEY` environment variables to an account that has access to the Azure Storage repository. +##### Shared Key Authentication (Default) + +When using Azure Storage with shared key authentication, you must set the `AZURE_STORAGE_ACCOUNT` and `AZURE_STORAGE_KEY` environment variables to an account that has access to the Azure Storage repository. If you don't know your `AZURE_STORAGE_KEY` and have your Azure CLI correctly configured, here's an example of how to find a key corresponding to your `AZURE_STORAGE_ACCOUNT`: @@ -184,6 +186,50 @@ $ export AZURE_STORAGE_ACCOUNT="account_name" $ export AZURE_STORAGE_KEY=$(az storage account keys list -n $AZURE_STORAGE_ACCOUNT --query "[0].value") ``` +##### Azure Managed Identity Authentication + +Triton supports Azure Managed Identity (MI) as an alternative to shared key +authentication. This eliminates the need to distribute or rotate storage account +keys and aligns with enterprise security best practices on Azure. + +To enable Managed Identity authentication, set the `AZURE_STORAGE_AUTH_TYPE` +environment variable: + +```bash +$ export AZURE_STORAGE_ACCOUNT="account_name" +$ export AZURE_STORAGE_AUTH_TYPE="managed_identity" +$ tritonserver --model-repository=as://account_name/container_name/path/to/model/repository ... +``` + +For **user-assigned Managed Identity**, additionally specify the client ID: + +```bash +$ export AZURE_STORAGE_AUTH_TYPE="managed_identity" +$ export AZURE_STORAGE_CLIENT_ID="" +``` + +You may also use `AZURE_STORAGE_AUTH_TYPE="default"` to activate the Azure +`DefaultAzureCredential` chain, which probes multiple credential sources in +order: environment variables, managed identity, Azure CLI, and others. This is +useful during local development but has slightly higher startup latency due to +the probing. + +**Prerequisites:** + +- The Managed Identity (system- or user-assigned) must be assigned the + **Storage Blob Data Reader** role (or broader) on the target storage + account or container. +- The Triton host (AKS pod, VM, VMSS, App Service, etc.) must have the + Managed Identity assigned. +- For AKS workloads, ensure that either pod identity or workload identity + federation is configured so that the pod can obtain AAD tokens. + +**Sovereign clouds:** The Azure Identity SDK respects the `AZURE_AUTHORITY_HOST` +environment variable, so this authentication mode works for sovereign cloud +endpoints as well. + +##### Local Model Directory + By default, Triton makes a local copy of a remote model repository in a temporary folder, which is deleted after Triton server is shut down. If you would like to control where remote model repository is copied to, you may set the `TRITON_AZURE_MOUNT_DIRECTORY` environment variable to a path pointing to the existing folder on your local machine. @@ -235,6 +281,11 @@ export TRITON_CLOUD_CREDENTIAL_PATH="cloud_credential.json" "as://Account-002/Container": { "account_str": "", "account_key": "" + }, + "as://Account-MI/Container": { + "account_str": "AZURE_STORAGE_ACCOUNT", + "auth_type": "managed_identity", + "client_id": "" } } } diff --git a/qa/L0_storage_azure/test.sh b/qa/L0_storage_azure/test.sh index 805c081679..144344ffd8 100755 --- a/qa/L0_storage_azure/test.sh +++ b/qa/L0_storage_azure/test.sh @@ -137,7 +137,10 @@ sleep 10 # Test 1 Scenarios: # 1. access blob using shared key in envs -# 2. adding more scenarios in future +# 2. access blob using system-assigned managed identity +# 3. access blob using user-assigned managed identity +# 4. access blob using DefaultAzureCredential +# 5. adding more scenarios in future for ENV_VAR in "shared_key"; do SERVER_LOG=$SERVER_LOG_BASE.$ENV_VAR.log CLIENT_LOG=$CLIENT_LOG_BASE.$ENV_VAR.log @@ -169,6 +172,117 @@ for ENV_VAR in "shared_key"; do wait $SERVER_PID done +# Test 2: Managed Identity authentication +# Requires the test host (VM/AKS) to have a system-assigned managed identity +# with Storage Blob Data Reader on the test storage account. +# Skip if not running in an MI-capable environment. +if [ ! -z "$TEST_AZURE_MANAGED_IDENTITY" ]; then + echo -e "\n***\n*** Testing system-assigned Managed Identity\n***" + + # Save original key and clear it so it won't be used + SAVED_AZURE_STORAGE_KEY=$AZURE_STORAGE_KEY + unset AZURE_STORAGE_KEY + export AZURE_STORAGE_AUTH_TYPE="managed_identity" + + SERVER_LOG=$SERVER_LOG_BASE.managed_identity_system.log + CLIENT_LOG=$CLIENT_LOG_BASE.managed_identity_system.log + MODEL_REPO="${AS_URL}/models" + SERVER_ARGS="--model-repository=$MODEL_REPO --exit-timeout-secs=120" + + run_server + if [ "$SERVER_PID" == "0" ]; then + echo -e "\n***\n*** Failed to start $SERVER with system-assigned MI\n***" + cat $SERVER_LOG + RET=1 + else + set +e + run_unit_tests + set -e + + kill $SERVER_PID + wait $SERVER_PID + fi + + # Test 3: User-assigned Managed Identity (if client ID is provided) + if [ ! -z "$AZURE_STORAGE_CLIENT_ID" ]; then + echo -e "\n***\n*** Testing user-assigned Managed Identity\n***" + + SERVER_LOG=$SERVER_LOG_BASE.managed_identity_user.log + CLIENT_LOG=$CLIENT_LOG_BASE.managed_identity_user.log + SERVER_ARGS="--model-repository=$MODEL_REPO --exit-timeout-secs=120" + + run_server + if [ "$SERVER_PID" == "0" ]; then + echo -e "\n***\n*** Failed to start $SERVER with user-assigned MI\n***" + cat $SERVER_LOG + RET=1 + else + set +e + run_unit_tests + set -e + + kill $SERVER_PID + wait $SERVER_PID + fi + else + echo -e "\n***\n*** Skipping user-assigned MI test (AZURE_STORAGE_CLIENT_ID not set)\n***" + fi + + # Test 4: DefaultAzureCredential chain + echo -e "\n***\n*** Testing DefaultAzureCredential\n***" + export AZURE_STORAGE_AUTH_TYPE="default" + unset AZURE_STORAGE_CLIENT_ID + + SERVER_LOG=$SERVER_LOG_BASE.default_credential.log + CLIENT_LOG=$CLIENT_LOG_BASE.default_credential.log + SERVER_ARGS="--model-repository=$MODEL_REPO --exit-timeout-secs=120" + + run_server + if [ "$SERVER_PID" == "0" ]; then + echo -e "\n***\n*** Failed to start $SERVER with DefaultAzureCredential\n***" + cat $SERVER_LOG + RET=1 + else + set +e + run_unit_tests + set -e + + kill $SERVER_PID + wait $SERVER_PID + fi + + # Test: invalid auth_type should fail gracefully + echo -e "\n***\n*** Testing invalid auth_type (expect failure)\n***" + export AZURE_STORAGE_AUTH_TYPE="invalid_type" + + SERVER_LOG=$SERVER_LOG_BASE.invalid_auth_type.log + SERVER_ARGS="--model-repository=$MODEL_REPO --exit-timeout-secs=120 --exit-on-error=false" + + run_server + if [ "$SERVER_PID" != "0" ]; then + # Server started — but model load should have failed. Verify the log + # contains an authentication error rather than a successful load. + if grep -q "Unable to create Azure filesystem client" $SERVER_LOG; then + echo -e "*** invalid auth_type correctly rejected ***" + else + echo -e "\n***\n*** Expected auth failure with invalid auth_type\n***" + cat $SERVER_LOG + RET=1 + fi + kill $SERVER_PID + wait $SERVER_PID + else + echo -e "*** Server correctly refused to start with invalid auth_type ***" + fi + + # Restore environment for remaining tests + unset AZURE_STORAGE_AUTH_TYPE + unset AZURE_STORAGE_CLIENT_ID + export AZURE_STORAGE_KEY=$SAVED_AZURE_STORAGE_KEY +else + echo -e "\n***\n*** Skipping Managed Identity tests (TEST_AZURE_MANAGED_IDENTITY not set)\n***" +fi + # Test localization to a specified location export TRITON_AZURE_MOUNT_DIRECTORY=`pwd`/azure_localization_test From 81c82422220733b595372a68541feec868d4a7d0 Mon Sep 17 00:00:00 2001 From: J Wyman Date: Fri, 6 Mar 2026 13:54:13 -0500 Subject: [PATCH 2/2] Apply suggestions from code review --- docs/user_guide/model_repository.md | 2 +- qa/L0_storage_azure/test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user_guide/model_repository.md b/docs/user_guide/model_repository.md index 837898838b..1a641a45c7 100644 --- a/docs/user_guide/model_repository.md +++ b/docs/user_guide/model_repository.md @@ -1,5 +1,5 @@