Production Secrets Management in stevedunn/pacmanblazor

In stevedunn/pacmanblazor, the management of production secrets is crucial for ensuring the security and integrity of configuration settings like API keys, database connection strings, and other sensitive information. This document provides a detailed step-by-step outline of how secrets are managed.

Step 1: Environment Specific Configuration

Secrets are stored in environment-specific configuration files. In stevedunn/pacmanblazor, the appsettings.json file is complemented by an appsettings.Production.json file that contains production-specific values.

Example of appsettings.Production.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=prod.db.server;Database=mydb;User Id=myuser;Password=mypassword;"
  },
  "ApiKeys": {
    "ServiceX": "MY_PROD_API_KEY"
  }
}

Step 2: User Secrets for Development

During development, User Secrets can be used to store secrets outside of the source code. This is particularly useful to avoid hardcoding sensitive information into the repository. Configuration in development looks like:

{
  "ApiKeys": {
    "ServiceX": "MY_DEV_API_KEY"
  }
}

To set up User Secrets, you can run the following command in the project directory:

dotnet user-secrets init
dotnet user-secrets set "ApiKeys:ServiceX" "MY_DEV_API_KEY"

Step 3: Dependency Injection for Configuration

stevedunn/pacmanblazor uses Dependency Injection to access configuration settings throughout the application. The IConfiguration interface is provided in Startup.cs, which allows for easy access to both production and development configuration values.

Example of accessing the configuration:

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IKeyService>(new KeyService(Configuration["ApiKeys:ServiceX"]));
    }
}

Step 4: Deployment Pipeline Considerations

When deploying, ensure that sensitive configurations are set in the environment variables of the hosting environment instead of hardcoding them. This allows the application to dynamically load appropriate configurations based on the environment.

Example of using environment variables:

{
  "ConnectionStrings": {
    "DefaultConnection": "%DEFAULT_CONNECTION_STRING%"
  },
  "ApiKeys": {
    "ServiceX": "%SERVICE_X_API_KEY%"
  }
}

Step 5: Accessing Secret Values Securely

When accessing API keys or sensitive values, it’s recommended to abstract these values behind service interfaces. This encapsulates the access logic, ensuring that developers cannot access sensitive information directly.

Example service interface:

public interface IKeyService
{
    string GetServiceXApiKey();
}

public class KeyService : IKeyService
{
    private readonly string _serviceXApiKey;

    public KeyService(string serviceXApiKey)
    {
        _serviceXApiKey = serviceXApiKey;
    }

    public string GetServiceXApiKey() => _serviceXApiKey;
}

Step 6: Secure Storage Solutions

For advanced use cases, integrating a secure storage solution such as Azure Key Vault or AWS Secrets Manager is recommended. This allows for centralized management of secrets and policies regarding access.

Example implementation might look like this:

public class AzureKeyVaultService : IKeyService
{
    private readonly SecretClient _secretClient;

    public AzureKeyVaultService(SecretClient secretClient)
    {
        _secretClient = secretClient;
    }

    public async Task<string> GetServiceXApiKeyAsync()
    {
        KeyVaultSecret secret = await _secretClient.GetSecretAsync("ServiceXApiKey");
        return secret.Value;
    }
}

Conclusion

By structuring application secrets management as demonstrated, stevedunn/pacmanblazor can ensure sensitive information is handled securely, utilizing environment-specific configurations, user secrets during development, and best practices for production deployments.

Sources:

  • stevedunn/pacmanblazor project structure and configuration best practices.