From 57c6b47a5a71ad1e963421f599b431f364b6e272 Mon Sep 17 00:00:00 2001 From: Gina Triolo <51341242+gitri-ms@users.noreply.github.com> Date: Tue, 8 Aug 2023 13:18:27 -0700 Subject: [PATCH] Update READMEs, enforce tenant ID in deploy scripts --- README.md | 86 +++++++++++++++++++++++----------------- deploy/README.md | 87 ++++++++++++++++++++++++++++++----------- deploy/deploy-azure.ps1 | 11 +++--- deploy/deploy-azure.sh | 16 ++++---- deploy/main.bicep | 6 +-- deploy/main.json | 12 +++--- 6 files changed, 136 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index e0a27c858..9a3360be8 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,6 @@ You will need the following items to run the sample: - [.NET 7.0 SDK](https://dotnet.microsoft.com/download/dotnet/7.0) _(via Setup script)_ - [Node.js](https://nodejs.org/en/download) _(via Setup script)_ - [Yarn](https://classic.yarnpkg.com/docs/install) _(via Setup script)_ -- [Azure account](https://azure.microsoft.com/free) -- [Azure AD Tenant](https://learn.microsoft.com/azure/active-directory/develop/quickstart-create-new-tenant) - AI Service | AI Service | Requirement | @@ -26,11 +24,6 @@ You will need the following items to run the sample: | OpenAI | - [Account](https://platform.openai.com)
- [API key](https://platform.openai.com/account/api-keys) | # Instructions -## Register an application -1. Follow [these instructions](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app) and use the values below: - - `Supported account types`: "_Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)_" - - `Redirect URI (optional)`: _Single-page application (SPA)_ and use _http://localhost:3000_. -2. Take note of the `Application (client) ID`. Chat Copilot will use this ID for authentication. ## Windows 1. Open PowerShell as an administrator. @@ -46,19 +39,12 @@ You will need the following items to run the sample: 3. Configure Chat Copilot. ```powershell - .\Configure.ps1 -AIService {AI_SERVICE} -APIKey {API_KEY} -Endpoint {AZURE_OPENAI_ENDPOINT} -ClientId {AZURE_APPLICATION_ID} + .\Configure.ps1 -AIService {AI_SERVICE} -APIKey {API_KEY} -Endpoint {AZURE_OPENAI_ENDPOINT} ``` - `AI_SERVICE`: `AzureOpenAI` or `OpenAI`. - `API_KEY`: The `API key` for Azure OpenAI or for OpenAI. - `AZURE_OPENAI_ENDPOINT`: The Azure OpenAI resource `Endpoint` address. Omit `-Endpoint` if using OpenAI. - - `AZURE_APPLICATION_ID`: The `Application (client) ID` associated with the registered application. - - - (Optional): To set a specific Tenant Id, use the parameter: - - ```powershell - -TenantId {TENANT_ID} - ``` - > **IMPORTANT:** For `AzureOpenAI`, if you deployed models `gpt-35-turbo` and `text-embedding-ada-002` with custom names (instead of each own's given name), also use the parameters: @@ -104,19 +90,12 @@ You will need the following items to run the sample: 3. Configure Chat Copilot. ```bash - ./Configure.sh --aiservice {AI_SERVICE} --apikey {API_KEY} --endpoint {AZURE_OPENAI_ENDPOINT} --clientid {AZURE_APPLICATION_ID} + ./Configure.sh --aiservice {AI_SERVICE} --apikey {API_KEY} --endpoint {AZURE_OPENAI_ENDPOINT} ``` - `AI_SERVICE`: `AzureOpenAI` or `OpenAI`. - `API_KEY`: The `API key` for Azure OpenAI or for OpenAI. - `AZURE_OPENAI_ENDPOINT`: The Azure OpenAI resource `Endpoint` address. Omit `--endpoint` if using OpenAI. - - `AZURE_APPLICATION_ID`: The `Application (client) ID` associated with the registered application. - - - (Optional): To set a specific Tenant Id, use the parameter: - - ```bash - --tenantid {TENANT_ID} - ``` - > **IMPORTANT:** For `AzureOpenAI`, if you deployed models `gpt-35-turbo` and `text-embedding-ada-002` with custom names (instead of each own's given name), also use the parameters: @@ -134,17 +113,27 @@ You will need the following items to run the sample: > NOTE: Confirm pop-ups are not blocked and you are logged in with the same account used to register the application. -## (Optional) Enable backend authorization via Azure AD +## (Optional) Enable backend authentication via Azure AD + +By default, Chat Copilot runs locally without authentication, using a guest user profile. If you want to enable authentication with Azure Active Directory, follow the steps below. -1. Ensure you created the required application registration mentioned in [Start the WebApp FrontEnd application](#start-the-webapp-frontend-application) -2. Create a second application registration to represent the web api - > For more details on creating an application registration, go [here](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). +### Requirements + +- [Azure account](https://azure.microsoft.com/free) +- [Azure AD Tenant](https://learn.microsoft.com/azure/active-directory/develop/quickstart-create-new-tenant) + +### Instructions + +1. Create an [application registration](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app) for the frontend web app, using the values below + - `Supported account types`: "_Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)_" + - `Redirect URI (optional)`: _Single-page application (SPA)_ and use _http://localhost:3000_. - 1. Give the app registration a name - 2. As *Supported account type* choose `Accounts in any organizational directory and personal Microsoft Accounts` +2. Create a second [application registration](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app) for the backend web api, using the values below: + - `Supported account types`: "_Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)_" + - Do **not** configure a `Redirect URI (optional)` - 3. Do not configure a *Redirect Uri* +> Take note of the `Application (client) ID` for both app registrations as you will need them in future steps. 3. Expose an API within the second app registration 1. Select *Expose an API* from the menu @@ -180,15 +169,40 @@ You will need the following items to run the sample: 7. Click *Add permissions* -5. Update frontend web app configuration - 1. Open *.env* file +5. Run the Configure script with additional parameters to set up authentication. + + **Powershell** - 2. Set the value of `REACT_APP_AAD_API_SCOPE` to your application ID URI followed by the scope `access_as_user`, e.g. `api://12341234-1234-1234-1234-123412341234/access_as_user` + ```powershell + .\Configure.ps1 -AiService {AI_SERVICE} -APIKey {API_KEY} -Endpoint {AZURE_OPENAI_ENDPOINT} -FrontendClientId {FRONTEND_CLIENT_ID} -BackendClientId {BACKEND_CLIENT_ID} -TenantId {TENANT_ID} -Instance {AZURE_AD_INSTANCE} + ``` -6. Update backend web api configuration - 1. Open *appsettings.json* + **Bash** + ```bash + ./Configure.sh --aiservice {AI_SERVICE} --apikey {API_KEY} --endpoint {AZURE_OPENAI_ENDPOINT} --frontend-clientid {FRONTEND_APPLICATION_ID} --backend-clientid {BACKEND_APPLICATION_ID} --tenantid {TENANT_ID} --instance {AZURE_AD_INSTANCE} + ``` - 2. Set the value of `Authorization:AzureAd:Audience` to your application ID URI + - `AI_SERVICE`: `AzureOpenAI` or `OpenAI`. + - `API_KEY`: The `API key` for Azure OpenAI or for OpenAI. + - `AZURE_OPENAI_ENDPOINT`: The Azure OpenAI resource `Endpoint` address. Omit `-Endpoint` if using OpenAI. + - `FRONTEND_APPLICATION_ID`: The `Application (client) ID` associated with the application registration for the frontend. + - `BACKEND_APPLICATION_ID`: The `Application (client) ID` associated with the application registration for the backend. + - `TENANT_ID` : Your Azure AD tenant ID + - `AZURE_AD_INSTANCE` _(optional)_: The Azure AD cloud instance for the authenticating users. Defaults to `https://login.microsoftonline.com/`. + +6. Run Chat Copilot locally. This step starts both the backend API and frontend application. + + **Powershell** + + ```powershell + .\Start.ps1 + ``` + + **Bash** + + ```bash + ./Start.sh + ``` # Troubleshooting diff --git a/deploy/README.md b/deploy/README.md index 8b6ec841f..5c5db61e6 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,6 +1,6 @@ -# Deploying Copilot Chat +# Deploying Chat Copilot -This document details how to deploy CopilotChat's required resources to your Azure subscription. +This document details how to deploy Chat Copilot's required resources to your Azure subscription. ## Things to know @@ -11,16 +11,73 @@ This document details how to deploy CopilotChat's required resources to your Azu - `F1` and `D1` SKUs for the App Service Plans are not currently supported for this deployment in order to support private networking. +- Chat Copilot deployments use Azure Active Directory for authentication. All endpoints (except `/healthz`) require authentication to access. + # Configure your environment Before you get started, make sure you have the following requirements in place: +- [Azure AD Tenant](https://learn.microsoft.com/azure/active-directory/develop/quickstart-create-new-tenant) - Azure CLI (i.e., az) (if you already installed Azure CLI, make sure to update your installation to the latest version) - Windows, go to https://aka.ms/installazurecliwindows - Linux, run "`curl -L https://aka.ms/InstallAzureCli | bash`" - Azure Static Web App CLI (i.e., swa) can be installed by running "`npm install -g @azure/static-web-apps-cli`" - (Linux only) `zip` can be installed by running "`sudo apt install zip`" +## App registrations (identity) + +You will need two Azure Active Directory (AAD) application registrations -- one for the frontend web app and one for the backend API. + +> For details on creating an application registration, go [here](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). + +### Frontend app registration + +- Select `Single-page application (SPA)` as platform type, and set the redirect URI to `http://localhost:3000` +- Select `Accounts in any organizational directory and personal Microsoft Accounts` as supported account types. +- Make a note of the `Application (client) ID` from the Azure Portal for use in the `Deploy Frontend` step below. + +### Backend app registration + +- Do not set a redirect URI +- Select `Accounts in any organizational directory and personal Microsoft Accounts` as supported account types. +- Make a note of the `Application (client) ID` from the Azure Portal for use in the `Deploy Azure infrastructure` step below. + +### Linking the frontend to the backend +1. Expose an API within the backend app registration + 1. Select *Expose an API* from the menu + + 2. Add an *Application ID URI* + 1. This will generate an `api://` URI with a generated for you + + 2. Click *Save* to store the generated URI + + 3. Add a scope for `access_as_user` + 1. Click *Add scope* + + 2. Set *Scope name* to `access_as_user` + + 3. Set *Who can consent* to *Admins and users* + + 4. Set *Admin consent display name* and *User consent display name* to `Access Chat Copilot as a user` + + 5. Set *Admin consent description* and *User consent description* to `Allows the accesses to the Chat Copilot web API as a user` + +4. Add permissions to web app frontend to access web api as user + 1. Open app registration for web app frontend + + 2. Go to *API Permissions* + + 3. Click *Add a permission* + + 4. Select the tab *My APIs* + + 5. Choose the app registration representing the web api backend + + 6. Select permissions `access_as_user` + + 7. Click *Add permissions* + + # Deploy Azure Infrastructure The examples below assume you are using an existing Azure OpenAI resource. See the notes following each command for using OpenAI or creating a new Azure OpenAI resource. @@ -28,7 +85,7 @@ The examples below assume you are using an existing Azure OpenAI resource. See t ## PowerShell ```powershell -./deploy-azure.ps1 -Subscription {YOUR_SUBSCRIPTION_ID} -DeploymentName {YOUR_DEPLOYMENT_NAME} -AIService {AzureOpenAI or OpenAI} -AIApiKey {YOUR_AI_KEY} -AIEndpoint {YOUR_AZURE_OPENAI_ENDPOINT} +./deploy-azure.ps1 -Subscription {YOUR_SUBSCRIPTION_ID} -DeploymentName {YOUR_DEPLOYMENT_NAME} -AIService {AzureOpenAI or OpenAI} -AIApiKey {YOUR_AI_KEY} -AIEndpoint {YOUR_AZURE_OPENAI_ENDPOINT} -WebApiClientId {YOUR_BACKEND_APPLICATION_ID} -TenantId {YOUR_TENANT_ID} ``` - To use an existing Azure OpenAI resource, set `-AIService` to `AzureOpenAI` and include `-AIApiKey` and `-AIEndpoint`. @@ -39,7 +96,7 @@ The examples below assume you are using an existing Azure OpenAI resource. See t ```bash chmod +x ./deploy-azure.sh -./deploy-azure.sh --subscription {YOUR_SUBSCRIPTION_ID} --deployment-name {YOUR_DEPLOYMENT_NAME} --ai-service {AzureOpenAI or OpenAI} --ai-service-key {YOUR_AI_KEY} --ai-endpoint {YOUR_AZURE_OPENAI_ENDPOINT} +./deploy-azure.sh --subscription {YOUR_SUBSCRIPTION_ID} --deployment-name {YOUR_DEPLOYMENT_NAME} --ai-service {AzureOpenAI or OpenAI} --ai-service-key {YOUR_AI_KEY} --ai-endpoint {YOUR_AZURE_OPENAI_ENDPOINT} --client-id{YOUR_BACKEND_APPLICATION_ID} --tenant-id {YOUR_TENANT_ID} ``` - To use an existing Azure OpenAI resource, set `--ai-service` to `AzureOpenAI` and include `--ai-service-key` and `--ai-endpoint`. @@ -84,16 +141,6 @@ chmod +x ./deploy-webapi.sh ## Prerequisites -### App registration (identity) - -You will need an Azure Active Directory (AAD) application registration. - -> For details on creating an application registration, go [here](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). - -- Select `Single-page application (SPA)` as platform type, and set the redirect URI to `http://localhost:3000` -- Select `Accounts in any organizational directory and personal Microsoft Accounts` as supported account types for this sample. -- Make a note of the `Application (client) ID` from the Azure Portal for use in the `Deploy` below. - ### Install Azure's Static Web Apps CLI ```bash @@ -104,16 +151,16 @@ npm install -g @azure/static-web-apps-cli ```powershell -./deploy-webapp.ps1 -Subscription {YOUR_SUBSCRIPTION_ID} -ResourceGroupName rg-{YOUR_DEPLOYMENT_NAME} -DeploymentName {YOUR_DEPLOYMENT_NAME} -ApplicationClientId {YOUR_APPLICATION_ID} +./deploy-webapp.ps1 -Subscription {YOUR_SUBSCRIPTION_ID} -ResourceGroupName rg-{YOUR_DEPLOYMENT_NAME} -DeploymentName {YOUR_DEPLOYMENT_NAME} -ApplicationClientId {YOUR_FRONTEND_APPLICATION_ID} ``` ## Bash ```bash -./deploy-webapp.sh --subscription {YOUR_SUBSCRIPTION_ID} --resource-group rg-{YOUR_DEPLOYMENT_NAME} --deployment-name {YOUR_DEPLOYMENT_NAME} --application-id {YOUR_APPLICATION_ID} +./deploy-webapp.sh --subscription {YOUR_SUBSCRIPTION_ID} --resource-group rg-{YOUR_DEPLOYMENT_NAME} --deployment-name {YOUR_DEPLOYMENT_NAME} --application-id {YOUR_FRONTEND_APPLICATION_ID} ``` -Your CopilotChat application is now deployed! +Your Chat Copilot application is now deployed! # Appendix @@ -124,12 +171,6 @@ Make sure to include your frontend's URL as an allowed origin in your deployment To do this, go on the Azure portal, select your Semantic Kernel App Service, then click on "CORS" under the "API" section of the resource menu on the left of the page. This will get you to the CORS page where you can add your allowed hosts. -## Authorization - -All of endpoints (except `/healthz`) require authorization to access. - -To view your CopilotChat API key: - ### PowerShell ```powershell diff --git a/deploy/deploy-azure.ps1 b/deploy/deploy-azure.ps1 index ba98dfbf9..c4efc182e 100644 --- a/deploy/deploy-azure.ps1 +++ b/deploy/deploy-azure.ps1 @@ -19,6 +19,11 @@ param( # Azure AD client ID for the Web API backend app registration $WebApiClientId, + [Parameter(Mandatory)] + [string] + # Azure AD tenant ID for authenticating users + $TenantId, + [Parameter(Mandatory)] [ValidateSet("AzureOpenAI", "OpenAI")] [string] @@ -53,10 +58,6 @@ param( # Azure AD cloud instance for authenticating users $AzureAdInstance = "https://login.microsoftonline.com/", - [string] - # Azure AD tenant ID for authenticating users - $AzureAdTenantId = "common", - [ValidateSet("Volatile", "AzureCognitiveSearch", "Qdrant")] [string] # What method to use to persist embeddings @@ -108,7 +109,7 @@ $jsonConfig = " `\`"aiApiKey`\`": { `\`"value`\`": `\`"$AIApiKey`\`" }, `\`"aiEndpoint`\`": { `\`"value`\`": `\`"$AIEndpoint`\`" }, `\`"azureAdInstance`\`": { `\`"value`\`": `\`"$AzureAdInstance`\`" }, - `\`"azureAdTenantId`\`": { `\`"value`\`": `\`"$AzureAdTenantId`\`" }, + `\`"azureAdTenantId`\`": { `\`"value`\`": `\`"$TenantId`\`" }, `\`"webApiClientId`\`": { `\`"value`\`": `\`"$WebApiClientId`\`"}, `\`"deployNewAzureOpenAI`\`": { `\`"value`\`": $(If ($DeployAzureOpenAI) {"true"} Else {"false"}) }, `\`"memoryStore`\`": { `\`"value`\`": `\`"$MemoryStore`\`" }, diff --git a/deploy/deploy-azure.sh b/deploy/deploy-azure.sh index 870214d19..be80a2dff 100755 --- a/deploy/deploy-azure.sh +++ b/deploy/deploy-azure.sh @@ -11,6 +11,7 @@ usage() { echo " -d, --deployment-name DEPLOYMENT_NAME Name for the deployment (mandatory)" echo " -s, --subscription SUBSCRIPTION Subscription to which to make the deployment (mandatory)" echo " -c, --client-id WEBAPI_CLIENT_ID Azure AD client ID for the Web API backend app registration (mandatory)" + echo " -t, --tenant-id AZURE_AD_TENANT_ID Azure AD tenant ID for authenticating users (mandatory)" echo " -ai, --ai-service AI_SERVICE_TYPE Type of AI service to use (i.e., OpenAI or AzureOpenAI)" echo " -aikey, --ai-service-key AI_SERVICE_KEY API key for existing Azure OpenAI resource or OpenAI account" echo " -aiend, --ai-endpoint AI_ENDPOINT Endpoint for existing Azure OpenAI resource" @@ -19,9 +20,7 @@ usage() { echo " -wr, --web-app-region WEB_APP_REGION Region to deploy to the static web app into. This must be a region that supports static web apps. (default: \"West US 2\")" echo " -a, --app-service-sku WEB_APP_SVC_SKU SKU for the Azure App Service plan (default: \"B1\")" echo " -i, --instance AZURE_AD_INSTANCE Azure AD cloud instance for authenticating users" - echo " (default: \"https://login.microsoftonline.com/\")" - echo " -t, --tenant-id AZURE_AD_TENANT_ID Azure AD tenant ID for authenticating users (default: \"common\")" - echo " -ms, --memory-store Method to use to persist embeddings. Valid values are" + echo " (default: \"https://login.microsoftonline.com/\")" echo " -ms, --memory-store Method to use to persist embeddings. Valid values are" echo " \"AzureCognitiveSearch\" (default), \"Qdrant\" and \"Volatile\"" echo " -nc, --no-cosmos-db Don't deploy Cosmos DB for chat storage - Use volatile memory instead" echo " -ns, --no-speech-services Don't deploy Speech Services to enable speech as chat input" @@ -48,6 +47,11 @@ while [[ $# -gt 0 ]]; do shift shift ;; + -t|--tenant-id) + AZURE_AD_TENANT_ID="$2" + shift + shift + ;; -ai|--ai-service) AI_SERVICE_TYPE="$2" shift @@ -88,11 +92,6 @@ while [[ $# -gt 0 ]]; do shift shift ;; - -a|--tenant-id) - AZURE_AD_TENANT_ID="$2" - shift - shift - ;; -ms|--memory-store) MEMORY_STORE=="$2" shift @@ -180,7 +179,6 @@ az account set -s "$SUBSCRIPTION" : "${WEB_APP_SVC_SKU:="B1"}" : "${WEB_APP_REGION:="westus2"}" : "${AZURE_AD_INSTANCE:="https://login.microsoftonline.com/"}" -: "${AZURE_AD_TENANT_ID:="common"}" : "${MEMORY_STORE:="AzureCognitiveSearch"}" : "${NO_COSMOS_DB:=false}" : "${NO_SPEECH_SERVICES:=false}" diff --git a/deploy/main.bicep b/deploy/main.bicep index 8440b33f4..67efe4cd9 100644 --- a/deploy/main.bicep +++ b/deploy/main.bicep @@ -42,12 +42,12 @@ param aiApiKey string = '' @description('Azure AD client ID for the backend web API') param webApiClientId string = '' +@description('Azure AD tenant ID for authenticating users') +param azureAdTenantId string = '' + @description('Azure AD cloud instance for authenticating users') param azureAdInstance string = environment().authentication.loginEndpoint -@description('Azure AD tenant ID for authenticating users') -param azureAdTenantId string = 'common' - @description('Whether to deploy a new Azure OpenAI instance') param deployNewAzureOpenAI bool = false diff --git a/deploy/main.json b/deploy/main.json index a81002276..0af1d89dc 100644 --- a/deploy/main.json +++ b/deploy/main.json @@ -93,18 +93,18 @@ "description": "Azure AD client ID for the backend web API" } }, - "azureAdInstance": { + "azureAdTenantId": { "type": "string", - "defaultValue": "https://login.microsoftonline.com", + "defaultValue": "", "metadata": { - "description": "Azure AD cloud instance for authenticating users" + "description": "Azure AD tenant ID for authenticating users" } }, - "azureAdTenantId": { + "azureAdInstance": { "type": "string", - "defaultValue": "common", + "defaultValue": "https://login.microsoftonline.com", "metadata": { - "description": "Azure AD tenant ID for authenticating users" + "description": "Azure AD cloud instance for authenticating users" } }, "deployNewAzureOpenAI": {