-
Notifications
You must be signed in to change notification settings - Fork 90
Description
Issue Description
When clicking the "Test Azure AI Search Connection" button on the App Settings "Search & Extract" page with managed identity authentication enabled, the test connection failed with the following error:
Original Error Message:
NameError: name 'search_resource_manager' is not defined
Environment Configuration:
- Authentication Type: Managed Identity
- Azure Environment:
public(set in .env file) - Error occurred because the code tried to reference
search_resource_managerwhich wasn't defined for public cloud
Root Cause: The implementation used a REST API approach that required the search_resource_manager variable to construct authentication tokens. This variable wasn't defined for the public cloud environment, causing the initial error. Even if defined, the REST API approach with bearer tokens doesn't work properly with Azure AI Search's managed identity authentication.
Root Cause Analysis (with Copilot assistance)
The implementation used a REST API approach with manually acquired bearer tokens, which is fundamentally incompatible with how Azure AI Search handles managed identity authentication on the data plane.
Why the Approach Failed
Azure AI Search's data plane operations don't properly accept bearer tokens acquired through standard DefaultAzureCredential.get_token() flows and passed as HTTP Authorization headers. The authentication mechanism works differently:
# IMPLEMENTATION - FAILED
credential = DefaultAzureCredential()
arm_scope = f"{search_resource_manager}/.default"
token = credential.get_token(arm_scope).token
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.get(f"{endpoint}/indexes?api-version=2024-07-01", headers=headers)
# Returns: 403 ForbiddenProblems with this approach:
- Azure AI Search requires SDK-specific authentication handling
- Bearer tokens from
get_token()are rejected by the Search service - Token scope and refresh logic need specialized handling
- This issue occurs in all Azure environments (public, government, custom)
Why Other Services Work with REST API + Bearer Tokens
Some Azure services accept bearer tokens in REST API calls, but Azure AI Search requires the SDK to:
- Acquire tokens using the correct scope and flow
- Handle token refresh automatically
- Use Search-specific authentication headers
- Properly negotiate with the Search service's auth layer
The Solution
Instead of trying to define search_resource_manager for public cloud, the fix was to replace the REST API approach entirely with the SearchIndexClient SDK in route_backend_settings.py, which handles authentication correctly without needing the search_resource_manager variable.
Code Changes Summary
Before (REST API approach):
def _test_azure_ai_search_connection(payload):
# ... setup code ...
if direct_data.get('auth_type') == 'managed_identity':
credential = DefaultAzureCredential()
arm_scope = f"{search_resource_manager}/.default"
token = credential.get_token(arm_scope).token
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.get(f"{endpoint}/indexes?api-version=2024-07-01", headers=headers)
# ❌ Returns 403 ForbiddenAfter (SDK approach):
Tested with this modification and it works for public env.
def _test_azure_ai_search_connection(payload):
# ... setup code ...
if direct_data.get('auth_type') == 'managed_identity':
credential = DefaultAzureCredential()
# Use SDK which handles authentication properly
if AZURE_ENVIRONMENT in ("usgovernment", "custom"):
client = SearchIndexClient(
endpoint=endpoint,
credential=credential,
audience=search_resource_manager
)
else:
# For public cloud, don't use audience parameter
client = SearchIndexClient(
endpoint=endpoint,
credential=credential
)
# Test by listing indexes (simple operation to verify connectivity)
indexes = list(client.list_indexes())
# ✅ Works correctly