๐ Introduction
In every .NET Core (now .NET 6/7/8) application, you need to store configuration data — things like:
Database connection strings
API keys (Stripe, SendGrid, etc.)
Cloud credentials
JWT signing keys
Third-party service secrets
However, storing secrets directly in code or config files (like appsettings.json) is a major security risk.
That’s where .NET’s configuration system and secret management tools come in.
⚙️ Configuration System Overview
.NET Core uses a configuration provider model — meaning you can load configuration values from multiple sources, in this order (by default):
appsettings.json
appsettings.{Environment}.json (e.g., appsettings.Development.json)
Environment variables
User secrets (in development)
Command-line arguments
Azure Key Vault or other secret stores
๐ก Later sources override earlier ones, so you can replace defaults securely per environment.
๐️ 1. Using appsettings.json
Basic app configuration lives in appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyApp;Trusted_Connection=True;"
},
"JwtSettings": {
"Key": "dev-secret-key",
"Issuer": "MyApp"
}
}
Then, access configuration in your code:
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
var jwtKey = builder.Configuration["JwtSettings:Key"];
✅ Great for development, but never store real secrets here in production.
๐ 2. Managing Secrets Securely in Development (dotnet user-secrets)
When working locally, use User Secrets, which store sensitive data outside your project directory — typically in your user profile folder.
Step 1: Enable User Secrets
Run in your project directory:
dotnet user-secrets init
This adds a unique UserSecretsId to your .csproj file.
Example:
<PropertyGroup>
<UserSecretsId>c2a3d3a2-11b0-4b43-b9c1-d0d6c93b9f2f</UserSecretsId>
</PropertyGroup>
Step 2: Add a Secret
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=myserver;Database=prod;User Id=sa;Password=P@ssword!"
Step 3: Use It in Code
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
✅ Secrets are stored in:
Windows: %APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
macOS/Linux: ~/.microsoft/usersecrets/<user_secrets_id>/secrets.json
๐ก User secrets are not committed to source control, keeping them safe.
☁️ 3. Storing Secrets in Environment Variables
For production (especially in Docker or cloud environments), use environment variables.
Example:
export ConnectionStrings__DefaultConnection="Server=tcp:prod-db;Database=App;User Id=admin;Password=Prod123!"
Then read it in .NET:
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
๐ก Use double underscores (__) in environment variable names to represent nested JSON paths.
Example:
JwtSettings__Key="SuperSecureKey123"
๐งฐ 4. Using Azure Key Vault (Recommended for Cloud)
For enterprise or cloud apps, store secrets in Azure Key Vault, and let .NET fetch them securely.
Step 1: Create a Key Vault
In Azure Portal or CLI:
az keyvault create --name MyAppVault --resource-group MyResourceGroup --location eastus
Step 2: Add Secrets
az keyvault secret set --vault-name MyAppVault --name "ConnectionStrings--DefaultConnection" --value "Server=..."
Step 3: Connect .NET to Key Vault
Install the package:
dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
Then update your Program.cs:
using Azure.Identity;
var builder = WebApplication.CreateBuilder(args);
var keyVaultName = builder.Configuration["KeyVaultName"];
var uri = new Uri($"https://{keyVaultName}.vault.azure.net/");
builder.Configuration.AddAzureKeyVault(uri, new DefaultAzureCredential());
Now you can access secrets just like normal configuration values:
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
✅ Azure handles authentication via Managed Identity — no keys in your code.
๐งฉ 5. Protecting Configuration in Production
๐ธ Encrypt secrets at rest
If you must store secrets locally (e.g., on a VM), use Data Protection API (DPAPI) or a third-party encryption tool.
๐ธ Don’t log or display secrets
Avoid logging sensitive information in exceptions or logs.
๐ธ Use Managed Identities
Instead of storing credentials for Azure services, use Managed Identities to let your app authenticate automatically.
๐ธ Rotate secrets regularly
Use automation (e.g., Azure Key Vault rotation policies) to periodically rotate passwords, keys, and tokens.
๐ง 6. Binding Configuration to Strongly Typed Classes
You can bind configuration sections directly to custom C# objects.
Example:
public class JwtSettings
{
public string Key { get; set; }
public string Issuer { get; set; }
}
In Program.cs:
builder.Services.Configure<JwtSettings>(
builder.Configuration.GetSection("JwtSettings"));
In your controller or service:
public class AuthService
{
private readonly JwtSettings _jwtSettings;
public AuthService(IOptions<JwtSettings> jwtOptions)
{
_jwtSettings = jwtOptions.Value;
}
}
✅ Benefits:
Strong typing
IntelliSense support
Centralized configuration management
๐งช 7. Combining Multiple Configuration Sources
You can mix multiple sources safely.
Example in Program.cs:
builder.Configuration
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
.AddUserSecrets<Program>(optional: true)
.AddEnvironmentVariables()
.AddAzureKeyVault(new Uri($"https://{keyVaultName}.vault.azure.net/"), new DefaultAzureCredential());
๐ก This ensures that:
Defaults come from appsettings.json
Overrides come from secrets or Key Vault
Sensitive data never touches source control
✅ Best Practices Summary
Category Recommendation
Development Use dotnet user-secrets for local secret storage
Production Use environment variables or Azure Key Vault
Cloud Prefer Managed Identities to avoid hardcoded credentials
Security Never commit secrets to Git
Configuration Use strongly typed classes for cleaner code
Maintenance Rotate secrets and monitor access logs regularly
๐ฌ In Short
Managing secrets and configuration in .NET Core means separating sensitive information from your codebase, storing it securely, and using the .NET configuration system to inject it safely at runtime.
By combining tools like User Secrets, Environment Variables, and Azure Key Vault, you can keep your .NET applications both secure and scalable across all environments.
Learn Dot Net Course in Hyderabad
Read More
How to Scale Your Full Stack .NET Application on the Cloud
Introduction to Kubernetes with .NET Core
Using Docker for Full Stack .NET Development
How to Host Your .NET Core Application on AWS
Visit Our Quality Thought Institute in Hyderabad
Subscribe by Email
Follow Updates Articles from This Blog via Email
No Comments