Skip to content

Commit 4bc14dd

Browse files
feat: UpdateToManagedIdentity
1 parent 7314166 commit 4bc14dd

1 file changed

Lines changed: 55 additions & 3 deletions

File tree

EssentialCSharp.Chat.Shared/Extensions/ServiceCollectionExtensions.cs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
using Microsoft.Extensions.Configuration;
66
using Microsoft.Extensions.DependencyInjection;
77
using Microsoft.SemanticKernel;
8+
using Npgsql;
89

910
namespace EssentialCSharp.Chat.Common.Extensions;
1011

1112
public static class ServiceCollectionExtensions
1213
{
14+
private static readonly string[] PostgresScopes = ["https://ossrdbms-aad.database.windows.net/.default"];
15+
1316
/// <summary>
1417
/// Adds Azure OpenAI and related AI services to the service collection using Managed Identity
1518
/// </summary>
@@ -50,8 +53,8 @@ public static IServiceCollection AddAzureOpenAIServices(
5053
aiOptions.Endpoint,
5154
credential);
5255

53-
// Add PostgreSQL vector store
54-
services.AddPostgresVectorStore(postgresConnectionString);
56+
// Add PostgreSQL vector store with managed identity support
57+
services.AddPostgresVectorStoreWithManagedIdentity(postgresConnectionString, credential);
5558

5659
services.AddAzureOpenAIEmbeddingGenerator(
5760
aiOptions.VectorGenerationDeploymentName,
@@ -96,6 +99,55 @@ public static IServiceCollection AddAzureOpenAIServices(
9699
return services.AddAzureOpenAIServices(aiOptions, postgresConnectionString, credential);
97100
}
98101

102+
/// <summary>
103+
/// Adds PostgreSQL vector store with managed identity authentication support.
104+
/// NOTE: Token is obtained once at startup and will expire after ~1 hour.
105+
/// For long-running applications, consider restarting the application periodically
106+
/// or implementing a background service to refresh the connection.
107+
/// </summary>
108+
/// <param name="services">The service collection to add services to</param>
109+
/// <param name="connectionString">The PostgreSQL connection string (without password)</param>
110+
/// <param name="credential">The token credential to use for authentication. If null, DefaultAzureCredential will be used.</param>
111+
/// <returns>The service collection for chaining</returns>
112+
private static IServiceCollection AddPostgresVectorStoreWithManagedIdentity(
113+
this IServiceCollection services,
114+
string connectionString,
115+
TokenCredential? credential = null)
116+
{
117+
credential ??= new DefaultAzureCredential();
118+
119+
// Parse the connection string to extract host, database, and username
120+
var builder = new NpgsqlConnectionStringBuilder(connectionString);
121+
122+
// Check if this is an Azure PostgreSQL connection (contains .postgres.database.azure.com)
123+
bool isAzurePostgres = builder.Host?.Contains(".postgres.database.azure.com", StringComparison.OrdinalIgnoreCase) ?? false;
124+
125+
if (isAzurePostgres && string.IsNullOrEmpty(builder.Password))
126+
{
127+
// Get access token for Azure PostgreSQL using managed identity
128+
var tokenRequestContext = new TokenRequestContext(PostgresScopes);
129+
var accessToken = credential.GetToken(tokenRequestContext, default);
130+
131+
// Set the password to the access token
132+
builder.Password = accessToken.Token;
133+
134+
// Ensure SSL is enabled for Azure
135+
if (builder.SslMode == SslMode.Disable)
136+
{
137+
builder.SslMode = SslMode.Require;
138+
}
139+
140+
connectionString = builder.ToString();
141+
}
142+
143+
// Register the vector store using the connection string
144+
#pragma warning disable SKEXP0010 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
145+
services.AddPostgresVectorStore(connectionString);
146+
#pragma warning restore SKEXP0010
147+
148+
return services;
149+
}
150+
99151
/// <summary>
100152
/// Adds Azure OpenAI and related AI services to the service collection using API key authentication (legacy)
101153
/// </summary>
@@ -138,7 +190,7 @@ public static IServiceCollection AddAzureOpenAIServicesWithApiKey(
138190
aiOptions.Endpoint,
139191
apiKey);
140192

141-
// Add PostgreSQL vector store
193+
// Add PostgreSQL vector store (standard connection string with password)
142194
services.AddPostgresVectorStore(postgresConnectionString);
143195

144196
services.AddAzureOpenAIEmbeddingGenerator(

0 commit comments

Comments
 (0)