π How to Store Secrets Securely in .NET
When building .NET applications, youβll often need to handle secrets like API keys, connection strings, or credentials. Storing these securely is essential to prevent accidental exposure or security breaches.
In this guide, weβll explore the main methods for managing secrets in .NET:
- Configuration sources in .NET
- When to use each method
- Security best practices
- Practical examples using
IOptions<T>
- Managing secrets across environments (Dev, QA, Prod)
π 1. appsettings.json
Best suited for general, non-sensitive configuration.
{
"ApiSettings": {
"BaseUrl": "https://api.mysite.com",
"Timeout": 30
}
}
Access with:
var timeout = configuration["ApiSettings:Timeout"];
Or using IOptions<T>
for cleaner code:
public class ApiSettings
{
public string BaseUrl { get; set; }
public int Timeout { get; set; }
}
In Program.cs
:
builder.Services.Configure<ApiSettings>(
builder.Configuration.GetSection("ApiSettings"));
Then inject:
public class MyService
{
private readonly ApiSettings _apiSettings;
public MyService(IOptions<ApiSettings> options)
{
_apiSettings = options.Value;
}
public void CallApi()
{
var url = _apiSettings.BaseUrl;
var timeout = _apiSettings.Timeout;
// Use them
}
}
π§βπ» 2. User Secrets (Development Only)
Ideal for local development without hardcoding credentials.
- Add a
UserSecretsId
to your.csproj
:
<PropertyGroup>
<UserSecretsId>your-app-guid</UserSecretsId>
</PropertyGroup>
- Set a secret:
dotnet user-secrets set "ApiSettings:ApiKey" "super-secret"
Stored safely in OS-specific locations.
π 3. Environment Variables
Best for production and CI/CD pipelines.
export ApiSettings__ApiKey="prod-secret-key"
.NET reads these automatically. The __
maps to nested keys.
βοΈ 4. Azure Key Vault
Enterprise-grade storage with encryption and access controls.
Add the package:
dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
Then:
builder.Configuration.AddAzureKeyVault(
new Uri("https://myvault.vault.azure.net/"),
new DefaultAzureCredential()
);
Use Managed Identity for secure access.
π 5. Environment-Specific Config Files
.NET supports loading config per environment:
appsettings.json
appsettings.Development.json
appsettings.Production.json
Set the environment:
export ASPNETCORE_ENVIRONMENT=Development
.NET merges them automatically.
π Configuration Precedence
From lowest to highest priority:
appsettings.json
appsettings.{Env}.json
- User Secrets
- Environment Variables
- Command-line arguments
- Hardcoded values
β Best Practices
- Use
IOptions<T>
for maintainability - Never commit secrets
- Use environment variables or Key Vault for production
- Add
secrets.json
to.gitignore
- Leverage
ASPNETCORE_ENVIRONMENT
- Consider Vaults or secret managers for scale
π References
π Conclusion
Scenario | Recommended Method |
---|---|
Local Dev | User Secrets |
CI/CD or QA | Environment Variables |
Production | Env Vars + Azure Key Vault |
General config | AppSettings + IOptions |
Use the right tool in the right context to avoid leaks and ensure your app is robust and secure.