MathewTaylor.Doppler.Configuration 0.1.0

dotnet add package MathewTaylor.Doppler.Configuration --version 0.1.0
                    
NuGet\Install-Package MathewTaylor.Doppler.Configuration -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MathewTaylor.Doppler.Configuration" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MathewTaylor.Doppler.Configuration" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="MathewTaylor.Doppler.Configuration" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MathewTaylor.Doppler.Configuration --version 0.1.0
                    
#r "nuget: MathewTaylor.Doppler.Configuration, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MathewTaylor.Doppler.Configuration@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MathewTaylor.Doppler.Configuration&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=MathewTaylor.Doppler.Configuration&version=0.1.0
                    
Install as a Cake Tool

Doppler Configuration Provider for .NET

A Doppler secrets provider for Microsoft.Extensions.Configuration. It loads your Doppler secrets at host startup and merges them into IConfiguration, so the rest of your app reads them through the same IConfiguration / IOptions<T> surface as any other source — no Doppler-specific code in your domain.

This is the in-process equivalent of the AddAzureKeyVault(...) / AddSecretsManager(...) providers. The secret backend becomes one swappable Add…() line in Program.cs.

Unofficial. Community-maintained and not affiliated with or endorsed by Doppler, Inc. "Doppler" is a trademark of its respective owner.

Why not just the Doppler CLI? doppler run --name-transformer dotnet-env -- dotnet … is great and needs no code, but it requires the CLI on every host and makes the CLI the process parent. This provider loads secrets in-process via the Doppler API, which suits all-in-one Docker dev/test boxes and keeps the loading mechanism identical to your other configuration providers.

Packages

Package Purpose
MathewTaylor.Doppler.Configuration The provider. Dependency-light, no file IO or crypto. Reference everywhere.
MathewTaylor.Doppler.Configuration.FileCache Optional encrypted cold-start cache. Reference only where you want the fallback (typically dev/test, not production).

The cache abstraction (IDopplerSecretCache) and the Options.Cache hook live in core; only the concrete FileSecretCache ships in the add-on. A project that doesn't reference the add-on cannot call FileSecretCache — the fallback is excluded at compile time, not just by convention.

Install

dotnet add package MathewTaylor.Doppler.Configuration

# only where you want the cold-start fallback:
dotnet add package MathewTaylor.Doppler.Configuration.FileCache

The id Doppler.Extensions.Configuration is taken by an abandoned 2022 package, hence the MathewTaylor. prefix.

Quick start

using Doppler.Configuration;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddDoppler(options =>
{
    // Token resolves from DOPPLER_TOKEN if you don't set it here.
    options.Optional       = builder.Environment.IsDevelopment();
    options.ReloadInterval = TimeSpan.FromMinutes(5);
});

var app = builder.Build();

Provide the token via environment variable (recommended):

export DOPPLER_TOKEN="dp.st.dev.xxxxxxxx"
dotnet run

Key mapping

Doppler secret names are UPPER_SNAKE_CASE. Configuration keys are hierarchical, delimited by :. The default KeyMapper maps the __ separator to :, matching .NET's environment-variable convention:

Doppler secret Configuration key Binds to
DATABASE_URL DATABASE_URL config["DATABASE_URL"]
SMTP__HOST Smtp:Host SmtpOptions.Host
CONNECTIONSTRINGS__DEFAULT ConnectionStrings:Default config.GetConnectionString("Default")

Configuration keys are case-insensitive, so casing of the Doppler name doesn't matter for binding. Override options.KeyMapper for a different scheme.

Source ordering

Providers added later win. Add Doppler after appsettings.json and environment variables if Doppler should be authoritative, or before them if local overrides should take precedence:

builder.Configuration
    .AddJsonFile("appsettings.json")
    .AddEnvironmentVariables()
    .AddDoppler();   // Doppler overrides the above

Options

Option Default Description
ServiceToken DOPPLER_TOKEN env var Doppler service token (dp.st.…). Scoped to one project + config.
Project null Only needed for Service Account tokens.
Config null Only needed for Service Account tokens.
Optional false Swallow load failures and contribute no keys.
ReloadInterval null Re-fetch on this interval and trigger change tokens.
ApiHost https://api.doppler.com/ Override for gateways or test doubles.
MaxRetries 3 Extra attempts on 429/5xx/network errors (exponential backoff).
KeyMapper __ → : Maps a Doppler name to a configuration key.
SecretFilter null Predicate to include/exclude secrets by raw name.
Cache null Opt-in encrypted cold-start fallback (see below).
HttpClient null Supply your own client (e.g. from IHttpClientFactory).
HttpMessageHandler null Custom handler for the internal client (testing).

All-in-one Docker dev/test boxes

Pass the token into the container and let the app self-hydrate at startup — no CLI in the image:

# docker-compose.yml
services:
  app:
    build: .
    environment:
      DOPPLER_TOKEN: ${DOPPLER_TOKEN}   # from your shell / .env, never committed
builder.Configuration.AddDoppler(); // reads DOPPLER_TOKEN, fetches at boot

Live reload

Set ReloadInterval and consume via IOptionsMonitor<T>; bound options refresh automatically when a reload detects changes. Background reload failures are swallowed so a transient Doppler outage never crashes a running host.

Resilience and the cold-start cache

There are two distinct outage windows:

  • Doppler goes down while the app is running — already covered. Secrets stay in the provider's in-memory store after the first successful load, and background reloads never clear them on failure. No cache needed.
  • Cold start while Doppler is unreachable (container restart mid-outage) — the only real gap. With Optional = false the host won't boot; with Optional = true it boots with no secrets. For this case only, you can opt into an encrypted on-disk snapshot.

In production, failing fast on a cold start is usually safest — let your orchestrator retry. The cache is most useful on local/dev/test boxes. It lives in the separate MathewTaylor.Doppler.Configuration.FileCache package, is opt-in and always encrypted (no plaintext-on-disk default):

var key = Convert.FromHexString(Environment.GetEnvironmentVariable("DOPPLER_CACHE_KEY")!); // 32 bytes

builder.Configuration.AddDoppler(o =>
{
    o.Cache = FileSecretCache.WithAesGcm("/var/lib/myapp/doppler.snapshot", key);
});

On every successful fetch the snapshot is refreshed (AES-256-GCM, 0600 perms on Unix). If a startup fetch fails and a valid snapshot exists, the provider loads it (degraded but running) instead of throwing. A tampered or wrong-key snapshot is treated as no cache. Supply your own protect/unprotect delegates via the FileSecretCache constructor (e.g. Windows DPAPI) or implement IDopplerSecretCache for a different store.

Security notes

  • Secret values are never logged by this library.
  • Treat the service token like any credential — inject it via environment, never commit it.
  • Scoped service tokens (read-only, single config) are strongly preferred over personal tokens.

How it works

The provider implements the standard IConfigurationSource / ConfigurationProvider contract. At build time it calls Doppler's GET /v3/configs/config/secrets/download?format=json endpoint with Authorization: Bearer <token>, flattens the returned JSON object, applies the key mapper, and populates the provider's Data. Loading is sync-over-async inside Load() — the same approach the framework's own Azure Key Vault provider uses — and runs once at startup, off the request path.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on MathewTaylor.Doppler.Configuration:

Package Downloads
MathewTaylor.Doppler.Configuration.FileCache

Optional encrypted on-disk cold-start cache for MathewTaylor.Doppler.Configuration. Lets a host fall back to a last-known-good snapshot when Doppler is unreachable at startup. Intended for development and test environments. Reference this package only where you want the fallback (typically not production). Unofficial: community-maintained and not affiliated with or endorsed by Doppler, Inc.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 338 6/30/2026