|
46 | 46 | "+ [Visual Studio Code](https://code.visualstudio.com/download) with the [Python extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) and [Jupyter package](https://pypi.org/project/jupyter/)." |
47 | 47 | ] |
48 | 48 | }, |
| 49 | + { |
| 50 | + "cell_type": "markdown", |
| 51 | + "id": "1a2379a9", |
| 52 | + "metadata": {}, |
| 53 | + "source": [ |
| 54 | + "## Configure access\n", |
| 55 | + "\n", |
| 56 | + "This notebook assumes that you're using Microsoft Entra ID for authentication and role assignments for authorization.\n", |
| 57 | + "\n", |
| 58 | + "To configure role-based access:\n", |
| 59 | + "\n", |
| 60 | + "1. Sign in to the [Azure portal](https://portal.azure.com).\n", |
| 61 | + "\n", |
| 62 | + "1. On your Azure AI Search service:\n", |
| 63 | + "\n", |
| 64 | + " 1. [Enable role-based access](https://learn.microsoft.com/azure/search/search-security-enable-roles).\n", |
| 65 | + " \n", |
| 66 | + " 1. [Create a system-assigned managed identity](https://learn.microsoft.com/azure/search/search-howto-managed-identities-data-sources#create-a-system-managed-identity).\n", |
| 67 | + " \n", |
| 68 | + " 1. [Assign the following roles](https://learn.microsoft.com/azure/search/search-security-rbac#how-to-assign-roles-in-the-azure-portal) to yourself.\n", |
| 69 | + " \n", |
| 70 | + " + **Search Service Contributor**\n", |
| 71 | + " \n", |
| 72 | + " + **Search Index Data Contributor**\n", |
| 73 | + " \n", |
| 74 | + " + **Search Index Data Reader**\n", |
| 75 | + "\n", |
| 76 | + " 1. Assign **Search Index Data Reader** to your Microsoft Foundry project.\n", |
| 77 | + "\n", |
| 78 | + "1. On your Microsoft Foundry resource:\n", |
| 79 | + "\n", |
| 80 | + " 1. Assign the following roles to yourself.\n", |
| 81 | + "\n", |
| 82 | + " + **Azure AI User**\n", |
| 83 | + "\n", |
| 84 | + " + **Azure AI Project Manager**\n", |
| 85 | + "\n", |
| 86 | + " 1. Assign **Cognitive Services User** to the managed identity of your search service." |
| 87 | + ] |
| 88 | + }, |
49 | 89 | { |
50 | 90 | "cell_type": "markdown", |
51 | 91 | "id": "1f40a871", |
|
59 | 99 | "+ Azure OpenAI (for the models deployed to your project)\n", |
60 | 100 | "+ Microsoft Foundry project\n", |
61 | 101 | "\n", |
62 | | - "You also need the resource ID of your project and at least **Azure AI Project Manager** access to the resource to create a connection for authentication. This connection is key based and requires an API key from your search service.\n", |
63 | | - "\n", |
64 | | - "Alternatively, you can omit the key and connect using a managed identity. For this option, you must enable a system-assigned managed identity on your project and assign the project the **Search Index Data Reader** role on your search service.\n", |
65 | | - "\n", |
66 | | - "You can find endpoints for Azure AI Search, Azure OpenAI, and Microsoft Foundry in the [Azure portal](https://portal.azure.com)." |
| 102 | + "You also need the resource ID of your project. You can find all of these values in the [Azure portal](https://portal.azure.com/)." |
67 | 103 | ] |
68 | 104 | }, |
69 | 105 | { |
|
80 | 116 | }, |
81 | 117 | { |
82 | 118 | "cell_type": "code", |
83 | | - "execution_count": 1, |
| 119 | + "execution_count": null, |
84 | 120 | "id": "e42b4a10", |
85 | 121 | "metadata": {}, |
86 | 122 | "outputs": [], |
87 | 123 | "source": [ |
88 | 124 | "from dotenv import load_dotenv\n", |
89 | 125 | "from azure.identity import DefaultAzureCredential\n", |
90 | | - "from azure.core.credentials import AzureKeyCredential\n", |
91 | 126 | "from azure.mgmt.core.tools import parse_resource_id\n", |
92 | 127 | "import os\n", |
93 | 128 | "\n", |
|
99 | 134 | "agent_model = os.getenv(\"AGENT_MODEL\", \"gpt-4.1-mini\")\n", |
100 | 135 | "agent_name = os.getenv(\"AGENT_NAME\", \"earth-knowledge-agent\")\n", |
101 | 136 | "endpoint = os.environ[\"AZURE_SEARCH_ENDPOINT\"]\n", |
102 | | - "search_api_key = os.getenv(\"AZURE_SEARCH_API_KEY\")\n", |
103 | 137 | "credential = DefaultAzureCredential()\n", |
104 | 138 | "knowledge_source_name = os.getenv(\"AZURE_SEARCH_KNOWLEDGE_SOURCE_NAME\", \"earth-knowledge-source\")\n", |
105 | 139 | "index_name = os.getenv(\"AZURE_SEARCH_INDEX\", \"earth-at-night\")\n", |
|
370 | 404 | "import requests\n", |
371 | 405 | "from azure.identity import get_bearer_token_provider\n", |
372 | 406 | "\n", |
373 | | - "if search_api_key:\n", |
374 | | - " connection = ConnectionPropertiesV2BasicResource(\n", |
375 | | - " properties=CustomKeysConnectionProperties(\n", |
376 | | - " category=\"RemoteTool\",\n", |
377 | | - " target=mcp_endpoint,\n", |
378 | | - " is_shared_to_all=True,\n", |
379 | | - " metadata={ \"ApiType\": \"Azure\" },\n", |
380 | | - " credentials=CustomKeys(\n", |
381 | | - " keys={ \"api-key\": search_api_key }\n", |
382 | | - " )\n", |
383 | | - " )\n", |
384 | | - " )\n", |
385 | | - "\n", |
386 | | - " mgmt_client = CognitiveServicesManagementClient(credential, subscription_id)\n", |
387 | | - " resource = mgmt_client.project_connections.create(\n", |
388 | | - " resource_group_name=resource_group,\n", |
389 | | - " account_name=account_name,\n", |
390 | | - " project_name=project_name,\n", |
391 | | - " connection_name=project_connection_name,\n", |
392 | | - " connection=connection\n", |
393 | | - " )\n", |
394 | | - "\n", |
395 | | - " print(f\"Connection '{resource.name}' created or updated successfully.\")\n", |
396 | | - "else:\n", |
397 | | - " # Requires the Foundry project to have Search Index Data Reader role on the search service\n", |
398 | | - " bearer_token_provider = get_bearer_token_provider(credential, \"https://management.azure.com/.default\")\n", |
399 | | - " headers = {\n", |
400 | | - " \"Authorization\": f\"Bearer {bearer_token_provider()}\",\n", |
401 | | - " }\n", |
402 | | - " response = requests.put(\n", |
403 | | - " f\"https://management.azure.com{project_resource_id}/connections/{project_connection_name}?api-version=2025-10-01-preview\",\n", |
404 | | - " headers=headers,\n", |
405 | | - " json={\n", |
406 | | - " \"name\": project_connection_name,\n", |
407 | | - " \"type\": \"Microsoft.MachineLearningServices/workspaces/connections\",\n", |
408 | | - " \"properties\": {\n", |
409 | | - " \"authType\": \"ProjectManagedIdentity\",\n", |
410 | | - " \"category\": \"RemoteTool\",\n", |
411 | | - " \"target\": mcp_endpoint,\n", |
412 | | - " \"isSharedToAll\": True,\n", |
413 | | - " \"audience\": \"https://search.azure.com/\",\n", |
414 | | - " \"metadata\": { \"ApiType\": \"Azure\" }\n", |
415 | | - " }\n", |
| 407 | + "# Requires the Foundry project to have Search Index Data Reader role on the search service\n", |
| 408 | + "bearer_token_provider = get_bearer_token_provider(credential, \"https://management.azure.com/.default\")\n", |
| 409 | + "headers = {\n", |
| 410 | + " \"Authorization\": f\"Bearer {bearer_token_provider()}\",\n", |
| 411 | + "}\n", |
| 412 | + "response = requests.put(\n", |
| 413 | + " f\"https://management.azure.com{project_resource_id}/connections/{project_connection_name}?api-version=2025-10-01-preview\",\n", |
| 414 | + " headers=headers,\n", |
| 415 | + " json={\n", |
| 416 | + " \"name\": project_connection_name,\n", |
| 417 | + " \"type\": \"Microsoft.MachineLearningServices/workspaces/connections\",\n", |
| 418 | + " \"properties\": {\n", |
| 419 | + " \"authType\": \"ProjectManagedIdentity\",\n", |
| 420 | + " \"category\": \"RemoteTool\",\n", |
| 421 | + " \"target\": mcp_endpoint,\n", |
| 422 | + " \"isSharedToAll\": True,\n", |
| 423 | + " \"audience\": \"https://search.azure.com/\",\n", |
| 424 | + " \"metadata\": { \"ApiType\": \"Azure\" }\n", |
416 | 425 | " }\n", |
417 | | - " )\n", |
418 | | - " response.raise_for_status()\n", |
419 | | - " print(f\"Connection '{project_connection_name}' created or updated successfully.\")" |
| 426 | + " }\n", |
| 427 | + ")\n", |
| 428 | + "response.raise_for_status()\n", |
| 429 | + "print(f\"Connection '{project_connection_name}' created or updated successfully.\")" |
420 | 430 | ] |
421 | 431 | }, |
422 | 432 | { |
|
0 commit comments