diff --git a/application/single_app/config.py b/application/single_app/config.py index dbea89df1..f139bbf3e 100644 --- a/application/single_app/config.py +++ b/application/single_app/config.py @@ -64,6 +64,7 @@ from io import BytesIO from typing import List +import azure.cognitiveservices.speech as speechsdk from azure.cosmos import CosmosClient, PartitionKey, exceptions from azure.cosmos.exceptions import CosmosResourceNotFoundError from azure.core.credentials import AzureKeyCredential diff --git a/application/single_app/functions_documents.py b/application/single_app/functions_documents.py index d7c431100..fd21bc816 100644 --- a/application/single_app/functions_documents.py +++ b/application/single_app/functions_documents.py @@ -4765,6 +4765,24 @@ def _split_audio_file(input_path: str, chunk_seconds: int = 540) -> List[str]: print(f"Produced {len(chunks)} WAV chunks: {chunks}") return chunks +# Azure Speech SDK helper to get speech config with fresh token +def _get_speech_config(settings, endpoint: str, locale: str): + """Get speech config with fresh token""" + if settings.get("speech_service_authentication_type") == "managed_identity": + credential = DefaultAzureCredential() + token = credential.get_token(cognitive_services_scope) + speech_config = speechsdk.SpeechConfig(endpoint=endpoint) + + # Set the authorization token AFTER creating the config + speech_config.authorization_token = token.token + else: + key = settings.get("speech_service_key", "") + speech_config = speechsdk.SpeechConfig(endpoint=endpoint, subscription=key) + + speech_config.speech_recognition_language = locale + print(f"[Debug] Speech config obtained successfully", flush=True) + return speech_config + def process_audio_document( document_id: str, user_id: str, @@ -4804,32 +4822,65 @@ def process_audio_document( # 3) transcribe each WAV chunk settings = get_settings() endpoint = settings.get("speech_service_endpoint", "").rstrip('/') - key = settings.get("speech_service_key", "") locale = settings.get("speech_service_locale", "en-US") - url = f"{endpoint}/speechtotext/transcriptions:transcribe?api-version=2024-11-15" all_phrases: List[str] = [] - for idx, chunk_path in enumerate(chunk_paths, start=1): - update_callback(current_file_chunk=idx, status=f"Transcribing chunk {idx}/{len(chunk_paths)}…") - print(f"Transcribing WAV chunk: {chunk_path}") - - with open(chunk_path, 'rb') as audio_f: - files = { - 'audio': (os.path.basename(chunk_path), audio_f, 'audio/wav'), - 'definition': (None, json.dumps({'locales':[locale]}), 'application/json') - } - headers = {'Ocp-Apim-Subscription-Key': key} - resp = requests.post(url, headers=headers, files=files) - try: - resp.raise_for_status() - except Exception as e: - print(f"[Error] HTTP error for {chunk_path}: {e}") - raise - result = resp.json() - phrases = result.get('combinedPhrases', []) - print(f"Received {len(phrases)} phrases") - all_phrases += [p.get('text','').strip() for p in phrases if p.get('text')] + # Fast Transcription API not yet available in sovereign clouds, so use SDK + if AZURE_ENVIRONMENT in ("usgovernment", "custom"): + for idx, chunk_path in enumerate(chunk_paths, start=1): + print(f"[Debug] Transcribing chunk {idx}: {chunk_path}") + + # Get fresh config (tokens expire after ~1 hour) + speech_config = _get_speech_config(settings, endpoint, locale) + + audio_config = speechsdk.AudioConfig(filename=chunk_path) + speech_recognizer = speechsdk.SpeechRecognizer( + speech_config=speech_config, + audio_config=audio_config + ) + + result = speech_recognizer.recognize_once() + if result.reason == speechsdk.ResultReason.RecognizedSpeech: + print(f"[Debug] Recognized: {result.text}") + all_phrases.append(result.text) + elif result.reason == speechsdk.ResultReason.NoMatch: + print(f"[Warning] No speech in {chunk_path}") + elif result.reason == speechsdk.ResultReason.Canceled: + print(f"[Error] {result.cancellation_details.reason}: {result.cancellation_details.error_details}") + raise RuntimeError(f"Transcription canceled for {chunk_path}: {result.cancellation_details.error_details}") + + else: + # Use the fast-transcription API if not in sovereign or custom cloud + url = f"{endpoint}/speechtotext/transcriptions:transcribe?api-version=2024-11-15" + for idx, chunk_path in enumerate(chunk_paths, start=1): + update_callback(current_file_chunk=idx, status=f"Transcribing chunk {idx}/{len(chunk_paths)}…") + print(f"[Debug] Transcribing WAV chunk: {chunk_path}") + + with open(chunk_path, 'rb') as audio_f: + files = { + 'audio': (os.path.basename(chunk_path), audio_f, 'audio/wav'), + 'definition': (None, json.dumps({'locales':[locale]}), 'application/json') + } + if settings.get("speech_service_authentication_type") == "managed_identity": + credential = DefaultAzureCredential() + token = credential.get_token(cognitive_services_scope) + headers = {'Authorization': f'Bearer {token.token}'} + else: + key = settings.get("speech_service_key", "") + headers = {'Ocp-Apim-Subscription-Key': key} + + resp = requests.post(url, headers=headers, files=files) + try: + resp.raise_for_status() + except Exception as e: + print(f"[Error] HTTP error for {chunk_path}: {e}") + raise + + result = resp.json() + phrases = result.get('combinedPhrases', []) + print(f"[Debug] Received {len(phrases)} phrases") + all_phrases += [p.get('text','').strip() for p in phrases if p.get('text')] # 4) cleanup WAV chunks for p in chunk_paths: diff --git a/application/single_app/requirements.txt b/application/single_app/requirements.txt index a85ce7b2c..a5467d9ab 100644 --- a/application/single_app/requirements.txt +++ b/application/single_app/requirements.txt @@ -52,4 +52,5 @@ cython pyyaml==6.0.2 aiohttp==3.12.15 html2text==2025.4.15 -matplotlib==3.10.7 \ No newline at end of file +matplotlib==3.10.7 +azure-cognitiveservices-speech==1.47.0 \ No newline at end of file diff --git a/application/single_app/route_frontend_admin_settings.py b/application/single_app/route_frontend_admin_settings.py index 5580f7b61..32498432e 100644 --- a/application/single_app/route_frontend_admin_settings.py +++ b/application/single_app/route_frontend_admin_settings.py @@ -668,6 +668,7 @@ def is_valid_url(url): 'speech_service_endpoint': form_data.get('speech_service_endpoint', '').strip(), 'speech_service_location': form_data.get('speech_service_location', '').strip(), 'speech_service_locale': form_data.get('speech_service_locale', '').strip(), + 'speech_service_authentication_type': form_data.get('speech_service_authentication_type', 'key'), 'speech_service_key': form_data.get('speech_service_key', '').strip(), 'metadata_extraction_model': form_data.get('metadata_extraction_model', '').strip(), diff --git a/application/single_app/static/js/admin/admin_settings.js b/application/single_app/static/js/admin/admin_settings.js index 308179871..2864bd3de 100644 --- a/application/single_app/static/js/admin/admin_settings.js +++ b/application/single_app/static/js/admin/admin_settings.js @@ -1654,6 +1654,15 @@ function setupToggles() { }); } + const speechAuthType = document.getElementById('speech_service_authentication_type'); + if (speechAuthType) { + speechAuthType.addEventListener('change', function () { + document.getElementById('speech_service_key_container').style.display = + (this.value === 'key') ? 'block' : 'none'; + markFormAsModified(); + }); + } + const officeAuthType = document.getElementById('office_docs_authentication_type'); const connStrGroup = document.getElementById('office_docs_storage_conn_str_group'); const urlGroup = document.getElementById('office_docs_storage_url_group'); @@ -3113,28 +3122,41 @@ function handleTabNavigation(stepNumber) { 5: 'ai-models-tab', // Embedding settings (now in AI Models tab) 6: 'search-extract-tab', // AI Search settings 7: 'search-extract-tab', // Document Intelligence settings - 8: 'workspaces-tab', // Video support - 9: 'workspaces-tab', // Audio support + 8: 'search-extract-tab', // Video support + 9: 'search-extract-tab', // Audio support 10: 'safety-tab', // Content safety - 11: 'system-tab', // User feedback and archiving (renamed from other-tab) + 11: 'safety-tab', // User feedback and archiving (changed from system-tab) 12: 'citation-tab' // Enhanced Citations and Image Generation }; // Activate the appropriate tab const tabId = stepToTab[stepNumber]; if (tabId) { - const tab = document.getElementById(tabId); - if (tab) { - // Use bootstrap Tab to show the tab - const bootstrapTab = new bootstrap.Tab(tab); - bootstrapTab.show(); - - // Scroll to the relevant section after a small delay to allow tab to switch - setTimeout(() => { - // For tabs that need to jump to specific sections - scrollToRelevantSection(stepNumber, tabId); - }, 300); + // Check if we're using sidebar navigation or tab navigation + const sidebarToggle = document.getElementById('admin-settings-toggle'); + + if (sidebarToggle) { + // Using sidebar navigation - call showAdminTab function + const tabName = tabId.replace('-tab', ''); // Remove '-tab' suffix + if (typeof showAdminTab === 'function') { + showAdminTab(tabName); + } else if (typeof window.showAdminTab === 'function') { + window.showAdminTab(tabName); + } + } else { + // Using Bootstrap tabs + const tab = document.getElementById(tabId); + if (tab) { + // Use bootstrap Tab to show the tab + const bootstrapTab = new bootstrap.Tab(tab); + bootstrapTab.show(); + } } + + // Scroll to the relevant section after a small delay to allow tab to switch + setTimeout(() => { + scrollToRelevantSection(stepNumber, tabId); + }, 300); } } @@ -3148,8 +3170,26 @@ function scrollToRelevantSection(stepNumber, tabId) { let targetElement = null; switch (stepNumber) { + case 1: // App title and logo + targetElement = document.getElementById('branding-section'); + break; + case 2: // GPT settings + targetElement = document.getElementById('gpt-configuration'); + break; + case 3: // GPT model selection + targetElement = document.getElementById('gpt_models_list')?.closest('.mb-3'); + break; case 4: // Workspaces toggle section - targetElement = document.getElementById('enable_user_workspace')?.closest('.card'); + targetElement = document.getElementById('personal-workspaces-section'); + break; + case 5: // Embedding settings + targetElement = document.getElementById('embeddings-configuration'); + break; + case 6: // AI Search settings + targetElement = document.getElementById('azure-ai-search-section'); + break; + case 7: // Document Intelligence settings + targetElement = document.getElementById('document-intelligence-section'); break; case 8: // Video file support targetElement = document.getElementById('enable_video_file_support')?.closest('.form-group'); @@ -3157,6 +3197,15 @@ function scrollToRelevantSection(stepNumber, tabId) { case 9: // Audio file support targetElement = document.getElementById('enable_audio_file_support')?.closest('.form-group'); break; + case 10: // Content safety + targetElement = document.getElementById('content-safety-section'); + break; + case 11: // User feedback and archiving + targetElement = document.getElementById('user-feedback-section'); + break; + case 12: // Enhanced citations and image generation + targetElement = document.getElementById('enhanced-citations-section'); + break; default: // For other steps, no specific scrolling break; @@ -3164,7 +3213,7 @@ function scrollToRelevantSection(stepNumber, tabId) { // If we found a target element, scroll to it if (targetElement) { - targetElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); + targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } @@ -3302,9 +3351,14 @@ function isStepComplete(stepNumber) { // Otherwise check settings const speechEndpoint = document.getElementById('speech_service_endpoint')?.value; - const speechKey = document.getElementById('speech_service_key')?.value; + const authType = document.getElementById('speech_service_authentication_type').value; + const key = document.getElementById('speech_service_key').value; - return speechEndpoint && speechKey; + if (!speechEndpoint || (authType === 'key' && !key)) { + return false; + } else { + return true; + } case 10: // Content safety - always complete (optional) case 11: // User feedback and archiving - always complete (optional) diff --git a/application/single_app/templates/admin_settings.html b/application/single_app/templates/admin_settings.html index e8dc1fe26..90a2c541a 100644 --- a/application/single_app/templates/admin_settings.html +++ b/application/single_app/templates/admin_settings.html @@ -369,7 +369,7 @@

9. Enable Audio File Support

Required: Audio support configuration is required if workspaces are enabled. -

Use the Audio Support settings in the Workspaces tab to enable and configure audio file processing.

+

Use the Audio Support settings on the Search & Extract tab to enable and configure audio file processing.

+ +
+ Note: If using Managed Identity authentication ensure the Service Principal has been assigned the Cognitive Services Speech Contributor role on the Azure Speech Service and that the Speech endpoint is configured with a custom domain name. + + +
@@ -2831,7 +2837,7 @@
Speech Service Settings
+ placeholder="https://.cognitiveservices.azure./">
@@ -2849,17 +2855,41 @@
Speech Service Settings
- + + +
+
+
- - + +
- +

diff --git a/docs/admin_configuration.md b/docs/admin_configuration.md index 9d3b8bf67..af8a9df17 100644 --- a/docs/admin_configuration.md +++ b/docs/admin_configuration.md @@ -2,37 +2,194 @@ [Return to Main](../README.md) - Once the application is running and you log in as a user assigned the Admin role, you can access the **Admin Settings** page. This UI provides a centralized location to configure most application features and service connections. ![alt text](./images/admin_settings_page.png) +## Setup Walkthrough + +The Admin Settings page includes an interactive **Setup Walkthrough** feature that guides you through the initial configuration process. This is particularly helpful for first-time setup. + +### Starting the Walkthrough + +- The walkthrough automatically appears on first-time setup when critical settings are missing +- You can manually launch it anytime by clicking the **"Start Setup Walkthrough"** button at the top of the Admin Settings page +- The walkthrough will automatically navigate to the relevant configuration tabs as you progress through each step + +### Walkthrough Features + +- **Automatic Tab Navigation**: As you move through steps, the walkthrough automatically switches to the relevant admin settings tab and scrolls to the appropriate section +- **Smart Step Skipping**: Steps that aren't applicable based on your configuration choices (e.g., workspace-dependent features) are automatically skipped +- **Real-time Validation**: The "Next" button becomes available only when required fields for the current step are completed +- **Progress Tracking**: Visual progress bar shows your completion status through the setup process +- **Flexible Navigation**: Use "Previous" and "Next" buttons to move between steps, or close the walkthrough at any time to configure settings manually + +### Walkthrough Steps Overview + +The walkthrough covers these key configuration areas in order: + +1. **Application Basics** (Optional) - App title and logo +2. **GPT API Settings** (Required) - Azure OpenAI GPT endpoint and authentication +3. **GPT Model Selection** (Required) - Select available GPT models for users +4. **Workspaces** (Optional) - Enable personal and/or group workspaces +5. **Embedding API** (Required if workspaces enabled) - Configure embedding service +6. **Azure AI Search** (Required if workspaces enabled) - Configure search indexing +7. **Document Intelligence** (Required if workspaces enabled) - Configure document processing +8. **Video Support** (Optional, workspace-dependent) - Configure video file processing +9. **Audio Support** (Optional, workspace-dependent) - Configure audio file processing +10. **Content Safety** (Optional) - Configure content filtering +11. **User Feedback & Archiving** (Optional) - Enable feedback and conversation archiving +12. **Enhanced Features** (Optional) - Enhanced citations and image generation + +The walkthrough automatically adjusts which steps are required based on your selections. For example, if you don't enable workspaces, embedding and search configuration steps become optional. + +## Configuration Sections + Key configuration sections include: -1. **General**: Application title, custom logo upload, landing page markdown text. -2. **GPT**: Configure Azure OpenAI endpoint(s) for chat models. Supports Direct endpoint or APIM. Allows Key or Managed Identity authentication. Test connection button. Select active deployment(s). - 1. Setting up Multi-model selection for users -3. **Embeddings**: Configure Azure OpenAI endpoint(s) for embedding models. Supports Direct/APIM, Key/Managed Identity. Test connection. Select active deployment. -4. **Image Generation** *(Optional)*: Enable/disable feature. Configure Azure OpenAI DALL-E endpoint. Supports Direct/APIM, Key/Managed Identity. Test connection. Select active deployment. -5. **Workspaces**: - - Enable/disable **Your Workspace** (personal docs). - - Enable/disable **My Groups** (group docs). Option to enforce `CreateGroups` RBAC role for creating new groups. - - Enable/disable **Multimedia Support** (Video/Audio uploads). Configure **Video Indexer** (Account ID, Location, Key, API Endpoint, Timeout) and **Speech Service** (Endpoint, Region, Key). - - Enable/disable **Metadata Extraction**. Select the GPT model used for extraction. - - Enable/disable **Document Classification**. Define classification labels and colors. -6. **Citations**: - - Standard Citations (basic text references) are always on. - - Enable/disable **Enhanced Citations**. Configure **Azure Storage Account Connection String** (or indicate Managed Identity use if applicable). -7. **Safety**: - - Enable/disable **Content Safety**. Configure endpoint (Direct/APIM), Key/Managed Identity. Test connection. - - Enable/disable **User Feedback**. - - Configure **Admin Access RBAC**: Option to require `SafetyViolationAdmin` or `FeedbackAdmin` roles for respective admin views. - - Enable/disable **Conversation Archiving**. -8. **Search & Extract**: - - Configure **Azure AI Search** connection (Endpoint, Key/Managed Identity). Test connection. (Primarily for testing, main indexing uses backend logic). - - Configure **Document Intelligence** connection (Endpoint, Key/Managed Identity). Test connection. -9. **Other**: - - Set **Maximum File Size** for uploads (in MB). - - Set **Conversation History Limit** (max number of past conversations displayed). - - Define the **Default System Prompt** used for the AI model. - - Enable/disable **File Processing Logs** (verbose logging for ingestion pipelines). +### 1. General +- **Branding**: Application title, custom logo upload (light and dark mode), favicon +- **Home Page Text**: Landing page markdown content with alignment options and optional editor +- **Appearance**: Default theme (light/dark mode) and navigation layout (top nav or left sidebar) +- **Health Check**: External health check endpoint configuration for monitoring systems +- **API Documentation**: Enable/disable Swagger/OpenAPI documentation endpoint +- **Classification Banner**: Security classification banner for data sensitivity indication +- **External Links**: Custom navigation links to external resources with configurable menu behavior +- **System Settings**: Maximum file size, conversation history limit, default system prompt + +### 2. AI Models +- **GPT Configuration**: + - Configure Azure OpenAI endpoint(s) for chat models + - Supports Direct endpoint or APIM (API Management) + - Allows Key or Managed Identity authentication + - Test connection button + - Select multiple active deployment(s) - users can choose from available models + - Multi-model selection for users + +- **Embeddings Configuration**: + - Configure Azure OpenAI endpoint(s) for embedding models + - Supports Direct/APIM, Key/Managed Identity + - Test connection + - Select active deployment + +- **Image Generation** *(Optional)*: + - Enable/disable feature + - Configure Azure OpenAI DALL-E endpoint + - Supports Direct/APIM, Key/Managed Identity + - Test connection + - Select active deployment + +### 3. Workspaces +- **Personal Workspaces**: Enable/disable "Your Workspace" (personal docs) +- **Group Workspaces**: + - Enable/disable "Groups" (group docs) + - Option to enforce `CreateGroups` RBAC role for creating new groups +- **Public Workspaces**: + - Enable/disable "Public" (public docs) + - Option to enforce `CreatePublicWorkspaces` RBAC role for creating new public workspaces +- **File Sharing**: + - Enable/disable file sharing capabilities between users and workspaces. +- **Metadata Extraction**: + - Enable/disable metadata extraction from documents + - Select the GPT model used for extraction +- **Multi-Modal Vision Analysis**: + - Enable vision-capable models for image analysis in addition to document OCR + - Automatic filtering of compatible GPT models (GPT-4o, GPT-4 Vision, etc.) +- **Document Classification**: + - Enable/disable classification features + - Define custom classification labels and colors + - Dynamic category management with inline editing + +### 4. Citations +- **Standard Citations**: Basic text references (always enabled) +- **Enhanced Citations**: + - Enable/disable enhanced citation features + - Configure Azure Storage Account Connection String or Service Endpoint with Managed Identity + - Store original files for direct reference and preview + +### 5. Safety +- **Content Safety**: + - Enable/disable content filtering + - Configure endpoint (Direct/APIM) + - Key/Managed Identity authentication + - Test connection +- **User Feedback**: + - Enable/disable thumbs up/down feedback on AI responses +- **Admin Access RBAC**: + - Option to require `SafetyViolationAdmin` role for safety violation admin views + - Option to require `FeedbackAdmin` role for feedback admin views +- **Conversation Archiving**: + - Enable/disable conversation archiving instead of permanent deletion + +### 6. Search & Extract +- **Azure AI Search**: + - Configure connection (Endpoint, Key/Managed Identity) + - Support for Direct or APIM routing + - Test connection +- **Document Intelligence**: + - Configure connection (Endpoint, Key/Managed Identity) + - Support for Direct or APIM routing + - Test connection +- **Multimedia Support** (Video/Audio uploads): + - **Video Files**: Configure Azure Video Indexer using Managed Identity authentication + - Resource Group, Subscription ID, Account Name, Location, Account ID + - API Endpoint, ARM API Version, Timeout + - **Audio Files**: Configure Speech Service + - Endpoint, Location/Region, Locale + - Key/Managed Identity authentication + +### 7. Agents +- **Agents Configuration**: + - Enable/disable Semantic Kernel-powered agents + - Configure workspace mode (per-user vs global agents) + - Agent orchestration settings (single agent vs multi-agent group chat) + - Manage global agents and select default/orchestrator agent +- **Actions Configuration**: + - Enable/disable core plugins (Time, HTTP, Wait, Math, Text, Fact Memory, Embedding) + - Configure user and group plugin permissions + - Manage custom OpenAPI plugins + +### 8. Scale +- **Redis Cache**: + - Enable distributed session storage for horizontal scaling + - Configure Redis endpoint and authentication (Key or Managed Identity) + - Test connection +- **Front Door**: + - Enable Azure Front Door integration + - Configure Front Door URL for authentication flows + - Supports global load balancing and custom domains + +### 9. Logging +- **Application Insights Logging**: + - Enable global logging for agents and orchestration + - Requires application restart to take effect +- **Debug Logging**: + - Enable/disable debug print statements + - Optional time-based auto-disable feature + - Warning: Collects tokens and keys during debug +- **File Processing Logs**: + - Enable logging of file processing events + - Logs stored in Cosmos DB file_processing container + - Optional time-based auto-disable feature + +## Navigation Options + +The Admin Settings page supports two navigation layouts: + +1. **Tab Navigation** (Default): Horizontal tabs at the top for switching between configuration sections +2. **Left Sidebar Navigation**: Collapsible left sidebar with grouped navigation items + - Can be set as the default for all users in General → Appearance settings + - Users can toggle between layouts individually + - The Setup Walkthrough works seamlessly with both navigation styles + +## Tips for Configuration + +- **Save Changes**: The floating "Save Settings" button in the bottom-right becomes active (blue) when you make changes +- **Test Connections**: Use the "Test Connection" buttons to verify your service configurations before saving +- **APIM vs Direct**: When using Azure API Management (APIM), you'll need to manually specify model names as automatic model fetching is not available +- **Managed Identity**: When using Managed Identity authentication, ensure your Service Principal has the appropriate roles assigned: + - **Azure OpenAI**: Cognitive Services OpenAI User role + - **Speech Service**: Cognitive Services Speech Contributor role (requires custom domain name on endpoint) + - **Video Indexer**: Appropriate Video Indexer roles for your account +- **Dependencies**: The walkthrough will alert you if required services aren't configured when you enable dependent features (e.g., workspaces require embeddings, AI Search, and Document Intelligence) +- **Required vs Optional**: The walkthrough clearly indicates which settings are required vs optional based on your configuration choices \ No newline at end of file diff --git a/docs/setup_instructions_special.md b/docs/setup_instructions_special.md index b46213f5f..81b4d4b01 100644 --- a/docs/setup_instructions_special.md +++ b/docs/setup_instructions_special.md @@ -25,7 +25,7 @@ To run the application in Azure Government cloud: - This ensures the application uses the correct Azure Government endpoints for authentication (MSAL) and potentially for fetching management plane details when using Managed Identity with direct endpoints. -3. **Endpoint URLs**: Ensure all endpoint URLs configured (in App Settings or via the Admin UI) point to the correct .usgovernment.azure.com (or specific service) domains. Azure OpenAI endpoints in Gov are different from Commercial. +3. **Endpoint URLs**: Ensure all endpoint URLs configured (in App Settings or via the Admin UI) point to the correct .azure.us (or specific service) domains. Azure OpenAI endpoints in Gov are different from Commercial. 4. **App Registration**: Ensure the App Registration is done within your Azure Government Azure AD tenant. The Redirect URI for the App Service will use the .azurewebsites.us domain. @@ -75,12 +75,12 @@ Using Managed Identity allows the App Service to authenticate to other Azure res | Target Service | Required Role | Notes | | --------------------- | ----------------------------------- | ------------------------------------------------------------ | | Azure OpenAI | Cognitive Services OpenAI User | Allows data plane access (generating completions, embeddings, images). | - | Azure AI Search | Search Index Data Contributor | Allows reading/writing data to search indexes. | + | Azure AI Search | Contributor & Search Index Data Contributor | Allows acquiring authentication token from Search resource manager and reading/writing data to search indexes. | | Azure Cosmos DB | Cosmos DB Built-in Data Contributor | Allows reading/writing data. Least privilege possible via custom roles. Key auth might be simpler. | | Document Intelligence | Cognitive Services User | Allows using the DI service for analysis. | - | Content Safety | Cognitive Services Contributor | Allows using the CS service for analysis. (Role name might vary slightly, check portal) | + | Content Safety | Azure AI Developer | Allows using the CS service for analysis. (Role name might vary slightly, check portal) | | Azure Storage Account | Storage Blob Data Contributor | Required for Enhanced Citations if using Managed Identity. Allows reading/writing blobs. | - | Azure Speech Service | Cognitive Services User | Allows using the Speech service for transcription. | + | Azure Speech Service | Cognitive Services Speech Contributor | Allows using the Speech service for transcription. | | Video Indexer | (Handled via VI resource settings) | VI typically uses its own Managed Identity to access associated Storage/Media Services. Check VI docs. | 3. **Configure Application to Use Managed Identity**: