AzureSecureAccess 1.2.0

dotnet add package AzureSecureAccess --version 1.2.0
                    
NuGet\Install-Package AzureSecureAccess -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AzureSecureAccess" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AzureSecureAccess" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="AzureSecureAccess" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AzureSecureAccess --version 1.2.0
                    
#r "nuget: AzureSecureAccess, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AzureSecureAccess@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AzureSecureAccess&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=AzureSecureAccess&version=1.2.0
                    
Install as a Cake Tool

Azure Secure Access

A modern .NET library for secure access to Azure Key Vault secrets, certificates, and encryption. Simplifies connecting to SQL Server databases using Always Encrypted with Azure Key Vault as the key store.


โœจ Features

  • Secrets Management: Retrieve and cache secrets from Azure Key Vault
  • Flexible Authentication: Client Secret, Certificate, Managed Identity, or DefaultAzureCredential
  • SQL Server Always Encrypted: First-class support with fluent builder API
  • Certificate Providers: Load X509 certificates from file, OS store, or Key Vault
  • Performance: Built-in caching to reduce API calls and latency
  • Clean Architecture: Domain-driven namespaces for intuitive discovery
  • Resilience: Built-in retry policies for Azure services using Polly
  • Observability: Structured logging with ILogger<T> across all providers (no secret values exposed)

๐Ÿ“ฆ Installation

dotnet add package AzureSecureAccess

๐Ÿš€ Quick Start

1. Authentication

Choose the authentication method that fits your scenario:

using AzureSecureAccess.Authentication;

// Client Secret (for service principals)
var credential = new ClientSecretCredentialProvider(tenantId, clientId, clientSecret);

// Certificate-based authentication
var credential = new CertificateCredentialProvider(tenantId, clientId, certificate);

// Managed Identity (Azure-hosted: App Service, AKS, VMs)
var credential = new ManagedIdentityCredentialProvider(); // System-assigned
var credential = new ManagedIdentityCredentialProvider(
    ManagedIdentityId.FromUserAssignedClientId("client-id")); // User-assigned

// DefaultAzureCredential (tries multiple methods automatically)
var credential = new DefaultCredentialProvider();

2. Retrieving Secrets

using AzureSecureAccess.Secrets;

var secretProvider = new KeyVaultSecretProvider("my-keyvault", credential.GetCredential());

// Get the latest version of a secret
string apiKey = await secretProvider.GetSecretValueAsync("ApiKey");

// Get a specific version
string oldKey = await secretProvider.GetSecretVersionValueAsync("ApiKey", "abc123version");
With Caching (reduces API calls)
var baseProvider = new KeyVaultSecretProvider("my-keyvault", credential.GetCredential());
using var cachedProvider = new CachedSecretProvider(baseProvider, TimeSpan.FromMinutes(30));

// First call hits Key Vault, subsequent calls use cache for 30 minutes
string secret = await cachedProvider.GetSecretValueAsync("ApiKey");

3. Working with Certificates

using AzureSecureAccess.Certificates;

// From local file
var localProvider = LocalCertificateProvider.FromFile("/path/to/cert.pfx");
var cert = localProvider.GetCertificate();

// From OS certificate store (by thumbprint)
var storeProvider = LocalCertificateProvider.FromStore("ABC123THUMBPRINT");
var cert = storeProvider.GetCertificate();

// From Azure Key Vault
var kvCertProvider = new KeyVaultCertificateProvider("my-keyvault", credential.GetCredential());
var certWithPrivateKey = await kvCertProvider.GetCertificateAsync("MyCertificate");

Notes:

  • PEM secrets (application/x-pem-file) are supported on .NET 8+ and load using the native PEM APIs.

4. SQL Server with Always Encrypted

Basic Usage
using AzureSecureAccess.SqlServer;

var credential = new DefaultCredentialProvider();

AlwaysEncryptedProvider.RegisterKeyVaultProvider(credential.GetCredential());

using var connection = new SqlConnection(
    "Server=myserver.database.windows.net;Database=MyDB;Column Encryption Setting=Enabled;");
await connection.OpenAsync();

// Encrypted columns are automatically decrypted!
Advanced: Fluent Builder with Key Vault Secrets
using AzureSecureAccess.SqlServer;

// Connection string stored directly
var connection = new SecureConnectionBuilder()
    .WithCredential(new ManagedIdentityCredentialProvider())
    .WithConnectionString("Server=...;Column Encryption Setting=Enabled;")
    .Build(); // OK for local connection strings

// Connection string stored in Key Vault (with caching)
var connection = await new SecureConnectionBuilder()
    .WithCredential(new DefaultCredentialProvider())
    .WithConnectionStringFromKeyVault("my-keyvault", "SqlConnectionString")
    .WithCaching(TimeSpan.FromMinutes(45)) // Cache the connection string
    .BuildAsync(); // Required for Key Vault to avoid deadlocks

await connection.OpenAsync();

5. Resilience and Error Handling

The library includes built-in resilience using Polly to handle transient errors (network issues, throttling) and provides domain-specific exceptions for fatal errors.

  • Automatic Retries: Operations are retried automatically on 408 (Timeout), 429 (Too Many Requests), and 5xx (Server Errors).
  • Specific Exceptions:
    • KeyVaultSecretNotFoundException: When a secret does not exist (404).
    • KeyVaultCertificateNotFoundException: When a certificate does not exist (404).
    • KeyVaultAccessDeniedException: When permissions are missing (403).
    • KeyVaultOperationException: For other Azure-related failures.

6. Observability and Diagnostics

All providers in the library support ILogger<T> for structured logging. You can pass your own logger or a ILoggerFactory to the fluent builders.

Key Features:
  • Traceability: Logs include Azure resource names (Key Vault URI, certificate names) but never the actual values of secrets or certificates.
  • Cache Insights: CachedSecretProvider logs HIT/MISS events to help optimize cache durations.
  • Authentication Visibility: Providers log which authentication method is being used (including Client ID and Tenant ID where applicable).
Example with SecureConnectionBuilder:
var connection = await new SecureConnectionBuilder()
    .WithCredential(credential)
    .WithConnectionStringFromKeyVault("my-vault", "MySecret")
    .WithLoggerFactory(myLoggerFactory) // All internal operations will be logged
    .BuildAsync();

๐Ÿ“š API Reference

Authentication Providers

Provider Use Case Example
ClientSecretCredentialProvider Service principal with secret Dev/test environments
CertificateCredentialProvider Service principal with certificate High-security production
ManagedIdentityCredentialProvider Azure-hosted resources App Service, AKS, VMs, Functions
DefaultCredentialProvider Automatic fallback chain Local dev + production flexibility

Secrets

Class Purpose
ISecretReader Abstraction for secret retrieval (Read-only)
ISecretManager Abstraction for secret management (Read/Write/Delete)
KeyVaultSecretProvider Direct access to Azure Key Vault secrets
CachedSecretProvider Decorator that caches secrets in memory (implements IDisposable)

Certificates

Class Purpose
ICertificateProvider Abstraction for certificate retrieval
LocalCertificateProvider Load from file system or OS certificate store
KeyVaultCertificateProvider Download certificates (with private keys) from Key Vault

SQL Server

Class Purpose
AlwaysEncryptedProvider Registers Azure Key Vault provider for Always Encrypted
SecureConnectionBuilder Fluent API to build SQL connections with encryption + Key Vault integration

๐Ÿ—๏ธ Architecture

The library is organized by domain, not technical layers:

AzureSecureAccess
โ”œโ”€โ”€ Authentication/       โ† How to authenticate with Azure
โ”œโ”€โ”€ Secrets/             โ† How to manage secrets
โ”œโ”€โ”€ Certificates/        โ† How to retrieve certificates
โ””โ”€โ”€ SqlServer/           โ† How to connect to SQL Server with encryption

Each namespace answers a specific question:

  • Authentication: How do I prove I'm authorized?
  • Secrets: Where are my configuration secrets?
  • Certificates: Where are my X509 certificates?
  • SqlServer: How do I connect securely to SQL Server?

๐Ÿ”’ Security Best Practices

  1. Use Managed Identity in production โ€” Eliminates credential management
  2. Enable caching โ€” Reduces API calls but be mindful of secret rotation
  3. Use Always Encrypted โ€” Protects data at rest and in transit from DBAs
  4. Store connection strings in Key Vault โ€” Never hardcode credentials
  5. Apply the least privilege โ€” Grant only necessary Key Vault permissions

๐Ÿงช Testing

Unit Tests (default)

dotnet test -f net8.0

Integration Tests (Key Vault + Always Encrypted)

Integration tests only run when RUN_INTEGRATION_TESTS=true is set.

Required environment variables:

  • RUN_INTEGRATION_TESTS=true
  • AZURE_TENANT_ID
  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET
  • AZURE_KEYVAULT_KEY_ID
  • AZURE_KEYVAULT_NAME (required for Key Vault secret/certificate tests)
  • AZURE_TESTS_KEEP_DB=true (optional, skips DB cleanup for debugging)

Alternative if you prefer to pass Key Vault name + key:

  • AZURE_KEYVAULT_NAME
  • AZURE_KEY_NAME
  • AZURE_KEY_VERSION

Provision a Key Vault + RSA key + app registration:

  • Bash: ./scripts/provision-keyvault.sh <resource-group> <location> <keyvault-name> <app-name>
  • PowerShell: ./scripts/provision-keyvault.ps1 -ResourceGroup <rg> -Location <loc> -KeyVaultName <kv> -AppName <app>

Run integration tests:

RUN_INTEGRATION_TESTS=true dotnet test -f net8.0

Azure Pipelines Variable Group

The pipeline expects a variable group named AzureSecureAccess-Integration. Create it in Azure DevOps and add these variables:

  • RUN_INTEGRATION_TESTS = true (or false to disable)
  • AZURE_TENANT_ID
  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET
  • AZURE_KEYVAULT_KEY_ID
  • AZURE_KEYVAULT_NAME
  • AZURE_TESTS_KEEP_DB (optional)

If you want a different group name, update azure-pipelines.yml.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 83 3/2/2026
1.1.0 89 3/1/2026