Skip to content

Commit c0e78db

Browse files
feat: Implemented Identity based Authentication
1 parent 090fc7a commit c0e78db

8 files changed

Lines changed: 125 additions & 115 deletions

File tree

App/backend-api/Microsoft.GS.DPS.Host/DependencyConfiguration/ServiceDependencies.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.GS.DPS.Storage.AISearch;
1313
using Microsoft.GS.DPSHost.AppConfiguration;
1414
using Microsoft.Extensions.DependencyInjection;
15+
using Microsoft.GS.DPSHost.Helpers;
1516

1617
namespace Microsoft.GS.DPSHost.ServiceConfiguration
1718
{
@@ -31,7 +32,7 @@ public static void Inject(IHostApplicationBuilder builder)
3132
return Kernel.CreateBuilder()
3233
.AddAzureOpenAIChatCompletion(deploymentName: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["ModelName"] ?? "",
3334
endpoint: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["Endpoint"] ?? "",
34-
apiKey: builder.Configuration.GetSection("Application:AIServices:GPT-4o-mini")["Key"] ?? "")
35+
credentials: AzureCredentialHelper.GetAzureCredential())
3536

3637
.Build();
3738
})
@@ -66,7 +67,7 @@ public static void Inject(IHostApplicationBuilder builder)
6667
.AddSingleton<TagUpdater>(x =>
6768
{
6869
var services = x.GetRequiredService<IOptions<Services>>().Value;
69-
return new TagUpdater(services.AzureAISearch.Endpoint, services.AzureAISearch.APIKey);
70+
return new TagUpdater(services.AzureAISearch.Endpoint, AzureCredentialHelper.GetAzureCredential());
7071

7172
})
7273

App/backend-api/Microsoft.GS.DPS/Microsoft.GS.DPS.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
<ItemGroup>
1010
<PackageReference Include="AutoMapper" Version="14.0.0" />
11+
<PackageReference Include="Azure.Identity" Version="1.14.1" />
1112
<PackageReference Include="Azure.Search.Documents" Version="11.6.1" />
1213
<PackageReference Include="FluentValidation" Version="12.0.0" />
1314
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />

App/backend-api/Microsoft.GS.DPS/Storage/AISearch/TagUpdater.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using System.Threading.Tasks;
55
using Azure;
6+
using Azure.Core;
67
using Azure.Search.Documents;
78
using Azure.Search.Documents.Models;
89

@@ -12,9 +13,9 @@ public class TagUpdater
1213
{
1314
private readonly SearchClient _searchClient;
1415

15-
public TagUpdater(string searchEndPoint, string searchAPIKey, string indexName = "default")
16+
public TagUpdater(string searchEndPoint, TokenCredential tokenCredential, string indexName = "default")
1617
{
17-
_searchClient = new SearchClient(new Uri(searchEndPoint), indexName, new AzureKeyCredential(searchAPIKey));
18+
_searchClient = new SearchClient(new Uri(searchEndPoint), indexName, tokenCredential);
1819
}
1920

2021
public async Task UpdateTags(string documentId, List<string> updatingTags)

App/kernel-memory/service/Core/DataFormats/Image/ImageContextDecoder.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.SemanticKernel.ChatCompletion;
1313
using Azure.AI.OpenAI;
1414
using System.Collections.Generic;
15+
using Azure.Identity;
1516

1617
namespace Microsoft.KernelMemory.DataFormats.Image
1718
{
@@ -32,7 +33,7 @@ public ImageContextDecoder(KernelMemoryConfig config, ILoggerFactory? loggerFact
3233
this._kernel = Kernel.CreateBuilder()
3334
.AddAzureOpenAIChatCompletion(deploymentName: (string)this._config.Services["AzureOpenAIText"]["Deployment"],
3435
endpoint: (string)this._config.Services["AzureOpenAIText"]["Endpoint"],
35-
apiKey: (string)this._config.Services["AzureOpenAIText"]["APIKey"])
36+
credentials: new DefaultAzureCredential())
3637
.Build();
3738
}
3839

App/kernel-memory/service/Core/DataFormats/Pdf/PdfMarkdownDecoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
using Azure.Core;
1616
using Azure;
1717
using Microsoft.KernelMemory.Configuration;
18+
using Azure.Identity;
1819

1920
namespace Microsoft.KernelMemory.DataFormats.Pdf;
2021
public sealed class PdfMarkdownDecoder(KernelMemoryConfig config, ILoggerFactory? loggerFactory = null) : IContentDecoder
2122
{
2223
private readonly ILogger<PdfDecoder> _log = (loggerFactory ?? DefaultLogger.Factory).CreateLogger<PdfDecoder>();
2324
private DocumentIntelligenceClient _client = null!; // Initialize _client as null
24-
private string _apiKey = (string)config.Services["AzureAIDocIntel"]["APIKey"];
2525
private string _endpoint = (string)config.Services["AzureAIDocIntel"]["Endpoint"];
2626

2727
/// <inheritdoc />
@@ -49,7 +49,7 @@ public async Task<FileContent> DecodeAsync(BinaryData data, CancellationToken ca
4949
Retry = { Delay = TimeSpan.FromSeconds(90), MaxDelay = TimeSpan.FromSeconds(180), MaxRetries = 3, Mode = RetryMode.Exponential },
5050
};
5151

52-
this._client = new DocumentIntelligenceClient(new Uri(this._endpoint), new AzureKeyCredential(this._apiKey), options);
52+
this._client = new DocumentIntelligenceClient(new Uri(this._endpoint), new DefaultAzureCredential(), options);
5353

5454
Operation<AnalyzeResult> operation = null;
5555
operation = await this._client.AnalyzeDocumentAsync(WaitUntil.Completed, analyzeDocumentOptions, cancellationToken).ConfigureAwait(false);

App/kernel-memory/service/Core/Handlers/KeywordExtractingHandler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Text.Json;
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using Azure.Identity;
89
using Microsoft.Extensions.Logging;
910
using Microsoft.KernelMemory.Diagnostics;
1011
using Microsoft.KernelMemory.Pipeline;
@@ -38,7 +39,7 @@ public KeywordExtractingHandler(
3839
this._kernel = Kernel.CreateBuilder()
3940
.AddAzureOpenAIChatCompletion(deploymentName: (string)this._config.Services["AzureOpenAIText"]["Deployment"],
4041
endpoint: (string)this._config.Services["AzureOpenAIText"]["Endpoint"],
41-
apiKey: (string)this._config.Services["AzureOpenAIText"]["APIKey"])
42+
credentials: new DefaultAzureCredential())
4243
.Build();
4344
}
4445

Deployment/resourcedeployment.ps1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,23 @@ try {
686686
Write-Host "Assign the role for aks system assigned managed identity to App Storage Queue Data Contributor role" -ForegroundColor Green
687687
az role assignment create --assignee $systemAssignedIdentity --role "Storage Queue Data Contributor" --scope "/subscriptions/$($deploymentResult.SubscriptionId)/resourceGroups/$($deploymentResult.ResourceGroupName)/providers/Microsoft.Storage/storageAccounts/$($deploymentResult.StorageAccountName)"
688688

689+
# Assign the role for aks system assigned managed identity to Azure Queue Data Contributor role with the scope of Storage Account
690+
Write-Host "Assign the role for aks system assigned managed identity to App Cognitive Services OpenAI User role" -ForegroundColor Green
691+
az role assignment create --assignee $systemAssignedIdentity --role "Cognitive Services OpenAI User" --scope "/subscriptions/$($deploymentResult.SubscriptionId)/resourceGroups/$($deploymentResult.ResourceGroupName)/providers/Microsoft.CognitiveServices/accounts/$($deploymentResult.AzOpenAiServiceName)"
692+
693+
# Assign the role for aks system assigned managed identity to Azure Queue Data Contributor role with the scope of Storage Account
694+
Write-Host "Assign the role for aks system assigned managed identity to App Search Index Data Contributor role" -ForegroundColor Green
695+
az role assignment create --assignee $systemAssignedIdentity --role "Search Index Data Contributor" --scope "/subscriptions/$($deploymentResult.SubscriptionId)/resourceGroups/$($deploymentResult.ResourceGroupName)/providers/Microsoft.Search/searchServices/$($deploymentResult.AzSearchServiceName)"
696+
697+
# Assign the role for aks system assigned managed identity to Azure Queue Data Contributor role with the scope of Storage Account
698+
Write-Host "Assign the role for aks system assigned managed identity to App Search Service Contributor role" -ForegroundColor Green
699+
az role assignment create --assignee $systemAssignedIdentity --role "Search Service Contributor" --scope "/subscriptions/$($deploymentResult.SubscriptionId)/resourceGroups/$($deploymentResult.ResourceGroupName)/providers/Microsoft.Search/searchServices/$($deploymentResult.AzSearchServiceName)"
700+
701+
# Assign the role for aks system assigned managed identity to Azure Queue Data Contributor role with the scope of Storage Account
702+
Write-Host "Assign the role for aks system assigned managed identity to App Cognitive Services User role" -ForegroundColor Green
703+
az role assignment create --assignee $systemAssignedIdentity --role "Cognitive Services User" --scope "/subscriptions/$($deploymentResult.SubscriptionId)/resourceGroups/$($deploymentResult.ResourceGroupName)/providers/Microsoft.CognitiveServices/accounts/$($deploymentResult.AzCognitiveServiceName)"
704+
705+
689706
# 8. Update aks nodepools to updated new role
690707
try {
691708
Write-Host "Upgrading node pools..." -ForegroundColor Cyan

infra/main.bicep

Lines changed: 95 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -396,112 +396,96 @@ module avmAppConfig 'br/public:avm/res/app-configuration/configuration-store:0.6
396396
}
397397
]
398398

399-
// keyValues: [
400-
// {
401-
// name: 'Application:AIServices:GPT-4o-mini:Endpoint'
402-
// value: avmOpenAi.outputs.endpoint
403-
// }
404-
// {
405-
// name: 'Application:AIServices:GPT-4o-mini:Key'
406-
// value: '' // Todo: avmOpenAi.outputs.
407-
// }
408-
// {
409-
// name: 'Application:AIServices:GPT-4o-mini:ModelName'
410-
// value: chatGpt.modelName
411-
// }
412-
// {
413-
// name: 'Application:Services:KernelMemory:Endpoint'
414-
// value: 'http://kernelmemory-service'
415-
// }
416-
// {
417-
// name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:ChatHistory:Collection'
418-
// value: 'ChatHistory'
419-
// }
420-
// {
421-
// name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:ChatHistory:Database'
422-
// value: 'DPS'
423-
// }
424-
// {
425-
// name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:DocumentManager:Collection'
426-
// value: 'Documents'
427-
// }
428-
// {
429-
// name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:DocumentManager:Database'
430-
// value: 'DPS'
431-
// }
432-
// {
433-
// name: 'Application:Services:PersistentStorage:CosmosMongo:ConnectionString'
434-
// value: avmCosmosDB.outputs.primaryReadWriteConnectionString
435-
// }
436-
// {
437-
// name: 'Application:Services:AzureAISearch:APIKey'
438-
// value: avmSearchSearchServices.outputs.exportedSecrets.primaryAdminKey
439-
// }
440-
// {
441-
// name: 'Application:Services:AzureAISearch:Endpoint'
442-
// value: 'https://${avmSearchSearchServices.outputs.name}.search.windows.net'
443-
// }
444-
// {
445-
// name: 'KernelMemory:Services:AzureAIDocIntel:APIKey'
446-
// value: documentIntelligence.outputs.exportedSecrets.primaryAdminKey
447-
// }
448-
// {
449-
// name: 'KernelMemory:Services:AzureAIDocIntel:Endpoint'
450-
// value: documentIntelligence.outputs.endpoint
451-
// }
452-
// {
453-
// name: 'KernelMemory:Services:AzureAISearch:APIKey'
454-
// value: avmSearchSearchServices.outputs.exportedSecrets.primaryAdminKey
455-
// }
456-
// {
457-
// name: 'KernelMemory:Services:AzureAISearch:Endpoint'
458-
// value: 'https://${avmSearchSearchServices.outputs.name}.search.windows.net'
459-
// }
460-
// {
461-
// name: 'KernelMemory:Services:AzureBlobs:Account'
462-
// value: avmStorageAccount.outputs.name
463-
// }
464-
// {
465-
// name: 'KernelMemory:Services:AzureBlobs:ConnectionString'
466-
// value: avmStorageAccount.outputs.primaryConnectionString
467-
// }
468-
// {
469-
// name: 'KernelMemory:Services:AzureBlobs:Container'
470-
// value: 'smemory'
471-
// }
472-
// {
473-
// name: 'KernelMemory:Services:AzureOpenAIEmbedding:APIKey'
474-
// value: '{azureopenaiembedding-apikey}'
475-
// }
476-
// {
477-
// name: 'KernelMemory:Services:AzureOpenAIEmbedding:Deployment'
478-
// value: embedding.deploymentName
479-
// }
480-
// {
481-
// name: 'KernelMemory:Services:AzureOpenAIEmbedding:Endpoint'
482-
// value: avmOpenAi.outputs.endpoint
483-
// }
484-
// {
485-
// name: 'KernelMemory:Services:AzureOpenAIText:APIKey'
486-
// value: '{azureopenaitext-apikey}'
487-
// }
488-
// {
489-
// name: 'KernelMemory:Services:AzureOpenAIText:Deployment'
490-
// value: chatGpt.deploymentName
491-
// }
492-
// {
493-
// name: 'KernelMemory:Services:AzureOpenAIText:Endpoint'
494-
// value: avmOpenAi.outputs.endpoint
495-
// }
496-
// {
497-
// name: 'KernelMemory:Services:AzureQueues:Account'
498-
// value: avmStorageAccount.outputs.name
499-
// }
500-
// {
501-
// name: 'KernelMemory:Services:AzureQueues:ConnectionString'
502-
// value: avmStorageAccount.outputs.primaryConnectionString
503-
// }
504-
// ]
399+
keyValues: [
400+
{
401+
name: 'Application:AIServices:GPT-4o-mini:Endpoint'
402+
value: avmOpenAi.outputs.endpoint
403+
}
404+
{
405+
name: 'Application:AIServices:GPT-4o-mini:ModelName'
406+
value: chatGpt.modelName
407+
}
408+
{
409+
name: 'Application:Services:KernelMemory:Endpoint'
410+
value: 'http://kernelmemory-service'
411+
}
412+
{
413+
name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:ChatHistory:Collection'
414+
value: 'ChatHistory'
415+
}
416+
{
417+
name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:ChatHistory:Database'
418+
value: 'DPS'
419+
}
420+
{
421+
name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:DocumentManager:Collection'
422+
value: 'Documents'
423+
}
424+
{
425+
name: 'Application:Services:PersistentStorage:CosmosMongo:Collections:DocumentManager:Database'
426+
value: 'DPS'
427+
}
428+
{
429+
name: 'Application:Services:PersistentStorage:CosmosMongo:ConnectionString'
430+
value: avmCosmosDB.outputs.primaryReadWriteConnectionString
431+
}
432+
{
433+
name: 'Application:Services:AzureAISearch:Endpoint'
434+
value: 'https://${avmSearchSearchServices.outputs.name}.search.windows.net'
435+
}
436+
{
437+
name: 'KernelMemory:Services:AzureAIDocIntel:Auth'
438+
value: 'AzureIdentity'
439+
}
440+
{
441+
name: 'KernelMemory:Services:AzureAIDocIntel:Endpoint'
442+
value: documentIntelligence.outputs.endpoint
443+
}
444+
{
445+
name: 'KernelMemory:Services:AzureAISearch:Auth'
446+
value: 'AzureIdentity'
447+
}
448+
{
449+
name: 'KernelMemory:Services:AzureAISearch:Endpoint'
450+
value: 'https://${avmSearchSearchServices.outputs.name}.search.windows.net'
451+
}
452+
{
453+
name: 'KernelMemory:Services:AzureBlobs:Account'
454+
value: avmStorageAccount.outputs.name
455+
}
456+
{
457+
name: 'KernelMemory:Services:AzureBlobs:Auth'
458+
value: 'AzureIdentity'
459+
}
460+
{
461+
name: 'KernelMemory:Services:AzureBlobs:Container'
462+
value: 'smemory'
463+
}
464+
{
465+
name: 'KernelMemory:Services:AzureOpenAIEmbedding:Deployment'
466+
value: embedding.deploymentName
467+
}
468+
{
469+
name: 'KernelMemory:Services:AzureOpenAIEmbedding:Endpoint'
470+
value: avmOpenAi.outputs.endpoint
471+
}
472+
{
473+
name: 'KernelMemory:Services:AzureOpenAIText:Deployment'
474+
value: chatGpt.deploymentName
475+
}
476+
{
477+
name: 'KernelMemory:Services:AzureOpenAIText:Endpoint'
478+
value: avmOpenAi.outputs.endpoint
479+
}
480+
{
481+
name: 'KernelMemory:Services:AzureQueues:Account'
482+
value: avmStorageAccount.outputs.name
483+
}
484+
{
485+
name: 'KernelMemory:Services:AzureQueues:Auth'
486+
value: 'AzureIdentity'
487+
}
488+
]
505489
// WAF aligned networking
506490
publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled'
507491
privateEndpoints: enablePrivateNetworking
@@ -615,7 +599,11 @@ module avmSearchSearchServices 'br/public:avm/res/search/search-service:0.9.1' =
615599
managedIdentities: { userAssignedResourceIds: [userAssignedIdentity!.outputs.resourceId] }
616600
replicaCount: 1
617601
partitionCount: 1
618-
602+
authOptions: {
603+
aadOrApiKey: {
604+
aadAuthFailureMode: 'http401WithBearerChallenge'
605+
}
606+
}
619607
roleAssignments: [
620608
{
621609
roleDefinitionIdOrName: 'Search Index Data Contributor' // Cognitive Search Contributor

0 commit comments

Comments
 (0)