Back to blog
Jun 14, 2025
3 min read

How to Store Secrets Securely in .NET: Environment Variables, AppSettings, User Secrets and More

Learn the best practices to handle secrets in .NET applications using environment variables, user secrets, configuration files, and Azure Key Vault. Keep your credentials safe and your architecture clean.

How to Store Secrets Securely in .NET – by AdriΓ‘n Bailador Panero


πŸ” 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.

  1. Add a UserSecretsId to your .csproj:
<PropertyGroup>
  <UserSecretsId>your-app-guid</UserSecretsId>
</PropertyGroup>
  1. 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:

  1. appsettings.json
  2. appsettings.{Env}.json
  3. User Secrets
  4. Environment Variables
  5. Command-line arguments
  6. 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

ScenarioRecommended Method
Local DevUser Secrets
CI/CD or QAEnvironment Variables
ProductionEnv Vars + Azure Key Vault
General configAppSettings + IOptions

Use the right tool in the right context to avoid leaks and ensure your app is robust and secure.