Sarıkaya Dev Logo

Securing .NET 8 gRPC Services with Mutual TLS and Azure Key Vault – Step‑by‑Step Guide

Mahmut Sarıkaya 4 min read 7 Views 0
Securing .NET 8 gRPC Services with Mutual TLS and Azure Key Vault – Step‑by‑Step Guide

Why secure gRPC with mTLS?

Imagine a microservice architecture where each call travels over an internal network, yet a single compromised node could read every payload. In 2023, 68% of data breaches involved insecure inter‑service communication. Mutual TLS (mTLS) eliminates that risk by authenticating both client and server with certificates, and Azure Key Vault provides a hardened store for those secrets.

Prerequisites

Before you start, ensure you have:

  • .NET 8 SDK (released November 2023)
  • Azure subscription with permission to create a Key Vault
  • OpenSSL installed on your development machine (version 1.1.1 or later)
  • Docker (optional, for local testing)

All tools run on Windows 10/11, macOS 13, or Ubuntu 22.04.

Create self‑signed certificates for mTLS

Use OpenSSL to generate a root CA, then issue a server and a client certificate. The root CA will be imported into Azure Key Vault and also into the trusted store of each service.

openssl genrsa -out ca.key 4096 && openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -subj "/CN=MyRootCA" -out ca.crt
openssl genrsa -out server.key 2048 && openssl req -new -key server.key -subj "/CN=grpcserver.local" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256
openssl genrsa -out client.key 2048 && openssl req -new -key client.key -subj "/CN=grpcclient" -out client.csr
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256

Convert the certificates to PFX for .NET consumption:

openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile ca.crt -passout pass:YourPfxPassword
openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt -certfile ca.crt -passout pass:YourPfxPassword

Store certificates in Azure Key Vault

Upload the PFX files to a Key Vault named GrpcSecurityVault. Use Azure CLI:

az keyvault create --name GrpcSecurityVault --resource-group MyRg --location eastus
az keyvault secret set --vault-name GrpcSecurityVault --name ServerCertificate --file server.pfx --encoding base64
az keyvault secret set --vault-name GrpcSecurityVault --name ClientCertificate --file client.pfx --encoding base64

Enable soft‑delete and purge‑protection to meet compliance requirements.

Configure the .NET 8 gRPC service for mTLS

In appsettings.json reference the Key Vault secret using Managed Identity:

{ "KeyVault": { "VaultUri": "https://grpcsecurityvault.vault.azure.net/" }, "Grpc": { "Port": 5001 } }

Program.cs loads the certificate at startup:

using Azure.Identity; using Azure.Security.KeyVault.Secrets; using System.Security.Cryptography.X509Certificates;
var builder = WebApplication.CreateBuilder(args);
var kvUri = builder.Configuration["KeyVault:VaultUri"];
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
var secret = client.GetSecret("ServerCertificate");
var serverPfx = Convert.FromBase64String(secret.Value.Value);
var serverCert = new X509Certificate2(serverPfx, "YourPfxPassword", X509KeyStorageFlags.MachineKeySet);
builder.WebHost.ConfigureKestrel(o =>
    o.ListenAnyIP(5001, lo => lo.UseHttps(https =>
        https.ServerCertificate = serverCert;
        https.ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode.RequireCertificate;
        https.CheckCertificateRevocation = false;
        https.AllowAnyClientCertificate(); // replaced by custom validation later
    )));
var app = builder.Build();
app.MapGrpcService<MySecureService>();
app.Run();

Replace AllowAnyClientCertificate with a callback that validates the client cert against the root CA stored in the vault.

Configure the .NET 8 gRPC client

The client also retrieves its PFX from Key Vault and configures the channel with GrpcChannelOptions:

using Grpc.Net.Client; using System.Net.Http; using System.Security.Cryptography.X509Certificates;
var secret = client.GetSecret("ClientCertificate");
var clientPfx = Convert.FromBase64String(secret.Value.Value);
var clientCert = new X509Certificate2(clientPfx, "YourPfxPassword", X509KeyStorageFlags.MachineKeySet);
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(clientCert);
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; // replace with proper validation
var httpClient = new HttpClient(handler);
var channel = GrpcChannel.ForAddress("https://grpcserver.local:5001", new GrpcChannelOptions { HttpClient = httpClient });
var client = new MySecureService.MySecureServiceClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = "Alice" });
Console.WriteLine(reply.Message);

In production, set ServerCertificateCustomValidationCallback to verify the server cert against the same root CA.

Test the secure connection

Run the server locally: dotnet run --project GrpcServer. Then execute the client project. If both sides present valid certificates, the console prints the greeting. To confirm mTLS enforcement, try launching the client without the client certificate – the handshake fails with a 403 error.

Conclusion

Combining mutual TLS with Azure Key Vault gives you end‑to‑end authentication, automated secret rotation, and compliance‑ready storage. The steps above—certificate generation, vault ingestion, service and client configuration—are repeatable for any .NET 8 gRPC ecosystem, whether you run on Azure Kubernetes Service, App Service, or on‑premises VMs. By adopting this pattern you reduce the attack surface dramatically and meet modern security standards for microservice communication.

Sources

  • Microsoft Docs – gRPC security in ASP.NET Core
  • Azure Key Vault documentation – secrets management
  • OpenSSL official cookbook – certificate creation

Author: Mahmut Sarıkaya — sarikayadev.com

Tags: #dotnet 8 #gRPC security #mutual TLS #mTLS #Azure Key Vault
Share:
M

Written by

Mahmut Sarıkaya

Software Developer

Comments

No comments yet. Be the first to share your thoughts!

Leave a Comment

5 + 7 =