Every ASP.NET Core application depends on secrets such as database connection strings, API keys, JWT signing keys, SMTP credentials, and cloud service tokens. If these secrets are stored in source code or committed to a Git repository, they become a serious security risk that can lead to data breaches and unauthorized access.

ASP.NET Core provides a flexible configuration system that supports multiple secret providers, including User Secrets for local development, Environment Variables for deployment, and Azure Key Vault for production environments. Choosing the appropriate secret storage mechanism is essential for building secure, maintainable applications.

Rather than hardcoding sensitive values, this article explains how to manage secrets securely throughout the application lifecycle.

Note: Secrets should never be committed to source control. Assume that any secret stored in a Git repository is eventually compromised.

Why Secrets Management Matters

Poor secret management can lead to:

Protecting secrets is one of the most fundamental application security practices.

Common Application Secrets

Production applications typically store:

Each should be stored outside the application codebase.

Secret Storage Options

Storage MethodDevelopmentProductionRecommended
appsettings.jsonLimitedNo
User SecretsDevelopment Only
Environment VariablesYes
Azure Key VaultBest for Azure
HashiCorp VaultEnterprise

The best storage option depends on the deployment environment and security requirements.

Understanding the Configuration Pipeline

ASP.NET Core loads configuration from multiple providers.

flowchart LR

A[appsettings.json]
B[Environment Variables]
C[User Secrets]
D[Azure Key Vault]

A --> E[Configuration]
B --> E
C --> E
D --> E

Later providers override earlier ones, allowing sensitive values to replace development defaults.

Using User Secrets

Initialize User Secrets for a project.

dotnet user-secrets init

Store a secret.

dotnet user-secrets set "ConnectionStrings:Default" "Server=.;Database=StoreDb;"

User Secrets are stored outside the project directory and should only be used during local development.

Reading Configuration

Retrieve secrets through the configuration system.

var connectionString =
    builder.Configuration
        .GetConnectionString("Default");

The application doesn't need to know whether the value came from User Secrets, Azure Key Vault, or an environment variable.

Using Environment Variables

Environment variables are commonly used in containers and cloud platforms.

Windows:

setx ConnectionStrings__Default "Server=prod-db;Database=StoreDb;"

Linux:

export ConnectionStrings__Default="Server=prod-db;Database=StoreDb;"

ASP.NET Core automatically maps double underscores (__) to configuration sections.

Using Azure Key Vault

Install the required package.

dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets

Register Azure Key Vault.

builder.Configuration.AddAzureKeyVault(
    new Uri("https://myvault.vault.azure.net/"),
    new DefaultAzureCredential());

Secrets stored in Azure Key Vault become available through the standard configuration API.

Configuration Priority

Configuration providers are loaded in a defined order.

PriorityProvider
HighestCommand-Line Arguments
HighEnvironment Variables
MediumAzure Key Vault
LowUser Secrets
Lowestappsettings.json

Higher-priority providers override values from lower-priority providers.

Accessing Secrets with Options Pattern

Bind configuration to strongly typed settings.

builder.Services.Configure<EmailOptions>(
    builder.Configuration.GetSection("Email"));

Consume the settings.

public class EmailService
{
    private readonly EmailOptions _options;

    public EmailService(
        IOptions<EmailOptions> options)
    {
        _options = options.Value;
    }
}

The Options pattern improves maintainability and avoids scattered configuration lookups.

Secret Rotation

Secrets should be rotated regularly.

Typical rotation process:

  1. Generate a new secret.

  2. Store it in the secret provider.

  3. Update the application configuration.

  4. Verify successful deployment.

  5. Remove the old secret.

Regular rotation reduces the impact of credential exposure.

Common Production Mistakes

ProblemRoot Cause
Secrets committed to GitStored in appsettings.json
API keys leakedHardcoded in source code
Shared development credentialsSame secrets across environments
Deployment failuresMissing environment variables
Manual secret updatesNo centralized secret management
Expired credentialsNo rotation policy

Most secret-related incidents are caused by poor operational practices rather than framework limitations.

Best Practices

Common Anti-Patterns

Avoid these common mistakes:

FAQ

Should connection strings be stored in appsettings.json?

Only for local development using non-sensitive values. Production connection strings should come from Environment Variables, Azure Key Vault, or another secure secret store.

What are User Secrets?

User Secrets are a development feature that stores sensitive configuration outside the project directory. They are not encrypted and should never be used in production.

Why use Azure Key Vault?

Azure Key Vault centralizes secret management, provides access control, supports secret rotation, and integrates seamlessly with ASP.NET Core configuration.

Can Environment Variables replace Azure Key Vault?

Yes, for many applications. However, Azure Key Vault provides additional security features such as centralized management, auditing, versioning, and controlled access, making it more suitable for production workloads.

Conclusion

Secure secret management is a critical component of every ASP.NET Core application. By keeping sensitive values out of source code, leveraging the built-in configuration system, and using appropriate secret providers for each environment, you can significantly reduce the risk of credential exposure and simplify application maintenance.

Whether you're developing locally with User Secrets, deploying containers with Environment Variables, or managing enterprise applications with Azure Key Vault, adopting a consistent secrets management strategy helps build secure, scalable, and production-ready .NET applications.