Read time: 7 minutes

If you’re building secure, cloud-native ASP.NET Core applications, there’s a good chance your database connection string still includes a password.

You may be storing it in Azure Key Vault, or maybe in an environment variable. But either way, it’s still a secret you have to manage, rotate, and protect.

But what if you didn’t need a password at all?

In today’s issue, I’ll show you how to connect your ASP.NET Core API to Azure Database for PostgreSQL using managed identities, so your app can authenticate securely without storing or handling secrets.

It’s not just more secure, it’s also a lot less maintenance.

Let’s take a look.

What is Azure Database for PostgreSQL?

Azure Database for PostgreSQL is a fully managed relational database service built on PostgreSQL.

It offers all the benefits you would expect of such a cloud offering:

  • Automatic backups
  • Automatic OS and database engine updates
  • Zone-redundant high availability
  • Predictable performance
  • Elastic scaling

But it’s also integrated with Microsoft Entra, which means you can secure access to the database using Azure managed identities instead of a traditional connection string.

And that’s where things get interesting.

How you’d normally connect to PostgreSQL

The best way to connect to PostgreSQL from a .NET application is by using the Npgsql database provider.

If you use Entity Framework Core, you can integrate Npgsql with the Npgsql.EntityFrameworkCore.PostgreSQL NuGet package.

Then in Program.cs you would configure your connection and your DBContext like this:

Now, what comes in that connection string? For an Azure PostgreSQL database, it will be something like this:

You definitely wouldn’t hardcode that into appsettings.json (not safe!). A better option would be a Key Vault secret, as I covered over here.

But even then, this approach is far from ideal because:

  • You’re still dealing with a password. Even if it’s hidden, it still exists.
  • That password will expire, and you’ll need to rotate it periodically.
  • Your app becomes dependent on secret management, adding more moving parts.

The bottom line is that passwords are fragile. But fortunately, we have better tools in the cloud for this.

Create a passwordless connection

The best approach to connect your app to PostgreSQL in the Azure cloud is to use a passwordless connection via a managed identity.

In the case of Azure PostgreSQL the main idea is to enable something like this:

Breaking it down:

  1. You assign a managed identity to your Web App (or Container App or whichever service you deploy into)
  2. Grant that identity access to your PostgreSQL database
  3. The Web App gets Microsoft Entra access tokens to talk to the database server

If you are new to Azure managed identities, I covered the basics over here, including an example with Azure Storage.

But with PostgreSQL it gets more challenging since you can’t just grant the identity RBAC access to the DB.

You need to create a user inside the database who represents the managed identity, and grant it the right permissions.

This is easier said than done, and can be challenging to enable manually. A better way is by using a Service Connector on your Web App:

That will make sure your managed identity gets the correct permissions to talk to your PostgreSQL DB with minimal chance of error.

I go through the service connector configuration, and everything needed for PostgreSQL passwordless authentication, step-by-step, in the bootcamp.

Next, time to write some code.

Using Npgsql with managed identities

The Npgsql library integration with managed identities is the most complicated I’ve seen so far, but at least version 9.0 made things a bit easier than before.

You still need a connection string to talk to the DB, since that’s the only way to tell your app what to connect to. But this time, your connection string will look something like this:

Notice the lack of a password there, and the use of a strangely named User Id. That’s the user that the service connector created for you in your DB, and which represents the managed identity.

Given that there’s no password, you could place that connection string in appsettings.json, but I prefer to keep it as an environment variable in my Web App to avoid revealing any cloud details in my repo.

In any case, your code will read the connection string just as before:

Then, install the Azure.Identity NuGet package and construct your credential object with the correct managed identity client id, which I usually keep as another environment variable:

Finally, we got the heavy part, which is the Npgsql configuration to use the managed identity to talk to the DB:

That code does the following:

  • Defines the Entra scope to get PostgreSQL-specific permissions
  • Configures an Npgsql data source to define how to acquire the password needed to talk to the DB
  • Sets up a password provider, which uses the credential object and the scope to retrieve an access token from Entra periodically
  • Every new token is cached for 24 hours
  • If it fails to get a token, it retries every 10 seconds

With that in place, deploy your app to Azure, and it should be able to start talking to PostgreSQL, no longer requiring any passwords.

Mission accomplished!

In Summary

Passwords don’t belong in the cloud.

If your app is running in Azure, use managed identities to connect to Azure Database for PostgreSQL securely, without hardcoding secrets or worrying about password rotation.

It’s not the easiest thing to configure, but it will pay off many times as you forget about passwords and focus on building and shipping features instead of managing secrets.

Cloud-native apps deserve cloud-native security.

Go passwordless.

Bootcamp Sale Ends Tomorrow: Save $100 + Bonus Course

The .NET Cloud Developer Bootcamp just got even better—Course 4: Azure for .NET Developers is now live.

To celebrate, you’ll get $100 off and a bonus course from my microservices program ($297 value) when you join during the launch sale.

This offer ends tomorrow at midnight.

If you’re ready to deploy secure, production-ready .NET apps to Azure using services like App Service, PostgreSQL, Microsoft Entra, and more, now’s the time.

Join the bootcamp before the deadline

Until next time!

Julio



Whenever you’re ready, there are 2 ways I can help you:

  1. .NET Cloud Developer Bootcamp: Everything you need to build production-ready .NET applications for the Azure cloud at scale.

  2. Promote your business to 20,000+ developers by sponsoring this newsletter.