Skip to content

Commit c1d8230

Browse files
sfi changes v1
1 parent 61b4421 commit c1d8230

File tree

16 files changed

+167
-50
lines changed

16 files changed

+167
-50
lines changed

infra/deploy_app_service.bicep

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ resource Website 'Microsoft.Web/sites@2020-06-01' = {
184184
serverFarmId: HostingPlanName
185185
siteConfig: {
186186
appSettings: [
187+
{
188+
name: 'APP_ENV'
189+
value: 'Prod'
190+
}
187191
{
188192
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
189193
value: reference(applicationInsightsId, '2015-05-01').InstrumentationKey

infra/main.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"_generator": {
66
"name": "bicep",
77
"version": "0.36.177.2456",
8-
"templateHash": "2238194529646818649"
8+
"templateHash": "3253509031453285119"
99
}
1010
},
1111
"parameters": {
@@ -359,7 +359,7 @@
359359
}
360360
},
361361
"solutionLocation": "[if(empty(parameters('AZURE_LOCATION')), resourceGroup().location, parameters('AZURE_LOCATION'))]",
362-
"uniqueId": "[toLower(uniqueString(parameters('environmentName'), subscription().id, variables('solutionLocation')))]",
362+
"uniqueId": "[toLower(uniqueString(parameters('environmentName'), subscription().id, variables('solutionLocation'), resourceGroup().name))]",
363363
"solutionPrefix": "[format('ca{0}', padLeft(take(variables('uniqueId'), 12), 12, '0'))]",
364364
"abbrs": "[variables('$fxv#0')]",
365365
"functionAppSqlPrompt": "Generate a valid T-SQL query to find {query} for tables and columns provided below:\r\n 1. Table: Clients\r\n Columns: ClientId, Client, Email, Occupation, MaritalStatus, Dependents\r\n 2. Table: InvestmentGoals\r\n Columns: ClientId, InvestmentGoal\r\n 3. Table: Assets\r\n Columns: ClientId, AssetDate, Investment, ROI, Revenue, AssetType\r\n 4. Table: ClientSummaries\r\n Columns: ClientId, ClientSummary\r\n 5. Table: InvestmentGoalsDetails\r\n Columns: ClientId, InvestmentGoal, TargetAmount, Contribution\r\n 6. Table: Retirement\r\n Columns: ClientId, StatusDate, RetirementGoalProgress, EducationGoalProgress\r\n 7. Table: ClientMeetings\r\n Columns: ClientId, ConversationId, Title, StartTime, EndTime, Advisor, ClientEmail\r\n Always use the Investment column from the Assets table as the value.\r\n Assets table has snapshots of values by date. Do not add numbers across different dates for total values.\r\n Do not use client name in filters.\r\n Do not include assets values unless asked for.\r\n ALWAYS use ClientId = {clientid} in the query filter.\r\n ALWAYS select Client Name (Column: Client) in the query.\r\n Query filters are IMPORTANT. Add filters like AssetType, AssetDate, etc. if needed.\r\n When answering scheduling or time-based meeting questions, always use the StartTime column from ClientMeetings table. Use correct logic to return the most recent past meeting (last/previous) or the nearest future meeting (next/upcoming), and ensure only StartTime column is used for meeting timing comparisons.\r\n Only return the generated SQL query. Do not return anything else.",
@@ -744,7 +744,7 @@
744744
"_generator": {
745745
"name": "bicep",
746746
"version": "0.36.177.2456",
747-
"templateHash": "1124249040831466979"
747+
"templateHash": "1343961496887433815"
748748
}
749749
},
750750
"parameters": {
@@ -1458,7 +1458,7 @@
14581458
"_generator": {
14591459
"name": "bicep",
14601460
"version": "0.36.177.2456",
1461-
"templateHash": "11899270249637077405"
1461+
"templateHash": "10199364008784095733"
14621462
}
14631463
},
14641464
"parameters": {
@@ -2244,7 +2244,7 @@
22442244
"_generator": {
22452245
"name": "bicep",
22462246
"version": "0.36.177.2456",
2247-
"templateHash": "10507186896960913919"
2247+
"templateHash": "7899619253922538038"
22482248
}
22492249
},
22502250
"parameters": {
@@ -2615,6 +2615,10 @@
26152615
"serverFarmId": "[parameters('HostingPlanName')]",
26162616
"siteConfig": {
26172617
"appSettings": [
2618+
{
2619+
"name": "APP_ENV",
2620+
"value": "Prod"
2621+
},
26182622
{
26192623
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
26202624
"value": "[reference(parameters('applicationInsightsId'), '2015-05-01').InstrumentationKey]"
@@ -2894,7 +2898,7 @@
28942898
"_generator": {
28952899
"name": "bicep",
28962900
"version": "0.36.177.2456",
2897-
"templateHash": "11899270249637077405"
2901+
"templateHash": "10199364008784095733"
28982902
}
28992903
},
29002904
"parameters": {

infra/scripts/fabric_scripts/create_fabric_items.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from azure.identity import DefaultAzureCredential
21
import base64
32
import json
43
import requests
@@ -8,7 +7,6 @@
87
import time
98

109

11-
# credential = DefaultAzureCredential()
1210
from azure.identity import AzureCliCredential
1311
credential = AzureCliCredential()
1412

infra/scripts/index_scripts/create_search_index.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@
4444
"clienttranscripts/meeting_transcripts_metadata/transcripts_metadata.csv"
4545
)
4646

47-
credential = DefaultAzureCredential(
48-
managed_identity_client_id=managed_identity_client_id
49-
)
47+
credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id) # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in local environment.
5048
token_provider = get_bearer_token_provider(
5149
credential,
5250
"https://cognitiveservices.azure.com/.default"

infra/scripts/index_scripts/create_sql_tables.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313

1414
def get_secrets_from_kv(kv_name, secret_name):
1515
key_vault_name = kv_name # Set the name of the Azure Key Vault
16-
credential = DefaultAzureCredential(
17-
managed_identity_client_id=managed_identity_client_id
18-
)
16+
credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id) # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in local environment.
1917
secret_client = SecretClient(
2018
vault_url=f"https://{key_vault_name}.vault.azure.net/", credential=credential
2119
) # Create a secret client object using the credential and Key Vault name
@@ -27,9 +25,7 @@ def get_secrets_from_kv(kv_name, secret_name):
2725
driver = "{ODBC Driver 18 for SQL Server}"
2826

2927

30-
credential = DefaultAzureCredential(
31-
managed_identity_client_id=managed_identity_client_id
32-
)
28+
credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id) # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in local environment.
3329

3430
token_bytes = credential.get_token(
3531
"https://database.windows.net/.default"
@@ -49,9 +45,7 @@ def get_secrets_from_kv(kv_name, secret_name):
4945
from azure.storage.filedatalake import DataLakeServiceClient
5046

5147
account_name = get_secrets_from_kv(key_vault_name, "ADLS-ACCOUNT-NAME")
52-
credential = DefaultAzureCredential(
53-
managed_identity_client_id=managed_identity_client_id
54-
)
48+
credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id) # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in local environment.
5549

5650
account_url = f"https://{account_name}.dfs.core.windows.net"
5751

infra/scripts/index_scripts/create_update_sql_dates.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212

1313
def get_secrets_from_kv(kv_name, secret_name):
1414
key_vault_name = kv_name # Set the name of the Azure Key Vault
15-
credential = DefaultAzureCredential(
16-
managed_identity_client_id=managed_identity_client_id
17-
)
15+
credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id) # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in local environment.
1816
secret_client = SecretClient(
1917
vault_url=f"https://{key_vault_name}.vault.azure.net/", credential=credential
2018
) # Create a secret client object using the credential and Key Vault name
@@ -32,9 +30,7 @@ def get_secrets_from_kv(kv_name, secret_name):
3230
from azure.storage.filedatalake import DataLakeServiceClient
3331

3432
account_name = get_secrets_from_kv(key_vault_name, "ADLS-ACCOUNT-NAME")
35-
credential = DefaultAzureCredential(
36-
managed_identity_client_id=managed_identity_client_id
37-
)
33+
credential = DefaultAzureCredential(managed_identity_client_id=managed_identity_client_id) # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in local environment.
3834

3935
account_url = f"https://{account_name}.dfs.core.windows.net"
4036

src/App/.env.sample

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ AZURE_SQL_SYSTEM_PROMPT="Generate a valid T-SQL query to find {query} for tables
6767
# Misc
6868
APPINSIGHTS_INSTRUMENTATIONKEY=
6969
AUTH_ENABLED="false"
70-
USE_INTERNAL_STREAM="True"
70+
USE_INTERNAL_STREAM="True"
71+
APP_ENV="dev"

src/App/app.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import uuid
77
from types import SimpleNamespace
88

9-
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
9+
from azure.identity import get_bearer_token_provider
10+
from backend.helpers.azure_credential_utils import get_azure_credential
11+
from backend.helpers.azure_credential_utils import get_azure_credential_async
1012
from azure.monitor.opentelemetry import configure_azure_monitor
1113

1214
# from quart.sessions import SecureCookieSessionInterface
@@ -185,7 +187,7 @@ def init_openai_client(use_data=SHOULD_USE_DATA):
185187
if not aoai_api_key:
186188
logging.debug("No AZURE_OPENAI_KEY found, using Azure AD auth")
187189
ad_token_provider = get_bearer_token_provider(
188-
DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"
190+
get_azure_credential(), "https://cognitiveservices.azure.com/.default"
189191
)
190192

191193
# Deployment
@@ -233,7 +235,7 @@ def init_cosmosdb_client():
233235
)
234236

235237
if not config.AZURE_COSMOSDB_ACCOUNT_KEY:
236-
credential = DefaultAzureCredential()
238+
credential = get_azure_credential()
237239
else:
238240
credential = config.AZURE_COSMOSDB_ACCOUNT_KEY
239241

src/App/backend/agents/agent_factory.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from typing import Optional
1111

1212
from azure.ai.projects import AIProjectClient
13-
from azure.identity import DefaultAzureCredential as DefaultAzureCredentialSync
14-
from azure.identity.aio import DefaultAzureCredential
13+
from backend.helpers.azure_credential_utils import get_azure_credential
14+
from backend.helpers.azure_credential_utils import get_azure_credential_async
1515
from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings
1616

1717
from backend.common.config import config
@@ -35,7 +35,7 @@ async def get_wealth_advisor_agent(cls):
3535
async with cls._lock:
3636
if cls._wealth_advisor_agent is None:
3737
ai_agent_settings = AzureAIAgentSettings()
38-
creds = DefaultAzureCredential()
38+
creds = await get_azure_credential_async()
3939
client = AzureAIAgent.create_client(
4040
credential=creds, endpoint=ai_agent_settings.endpoint
4141
)
@@ -76,7 +76,7 @@ async def get_search_agent(cls):
7676

7777
project_client = AIProjectClient(
7878
endpoint=config.AI_PROJECT_ENDPOINT,
79-
credential=DefaultAzureCredentialSync(),
79+
credential=get_azure_credential(),
8080
api_version="2025-05-01",
8181
)
8282

@@ -137,7 +137,7 @@ async def get_sql_agent(cls) -> dict:
137137

138138
project_client = AIProjectClient(
139139
endpoint=config.AI_PROJECT_ENDPOINT,
140-
credential=DefaultAzureCredentialSync(),
140+
credential=get_azure_credential(),
141141
api_version="2025-05-01",
142142
)
143143

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import os
2+
from azure.identity import ManagedIdentityCredential, DefaultAzureCredential
3+
from azure.identity.aio import ManagedIdentityCredential as AioManagedIdentityCredential, DefaultAzureCredential as AioDefaultAzureCredential
4+
5+
6+
async def get_azure_credential_async(client_id=None):
7+
"""
8+
Returns an Azure credential asynchronously based on the application environment.
9+
10+
If the environment is 'dev', it uses AioDefaultAzureCredential.
11+
Otherwise, it uses AioManagedIdentityCredential.
12+
13+
Args:
14+
client_id (str, optional): The client ID for the Managed Identity Credential.
15+
16+
Returns:
17+
Credential object: Either AioDefaultAzureCredential or AioManagedIdentityCredential.
18+
"""
19+
if os.getenv("APP_ENV", "prod").lower() == 'dev':
20+
return AioDefaultAzureCredential() # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in development
21+
else:
22+
return AioManagedIdentityCredential(client_id=client_id)
23+
24+
25+
def get_azure_credential(client_id=None):
26+
"""
27+
Returns an Azure credential based on the application environment.
28+
29+
If the environment is 'dev', it uses DefaultAzureCredential.
30+
Otherwise, it uses ManagedIdentityCredential.
31+
32+
Args:
33+
client_id (str, optional): The client ID for the Managed Identity Credential.
34+
35+
Returns:
36+
Credential object: Either DefaultAzureCredential or ManagedIdentityCredential.
37+
"""
38+
if os.getenv("APP_ENV", "prod").lower() == 'dev':
39+
return DefaultAzureCredential() # CodeQL [SM05139] Okay use of DefaultAzureCredential as it is only used in development
40+
else:
41+
return ManagedIdentityCredential(client_id=client_id)

0 commit comments

Comments
 (0)