CSharpEssentials.GcpSecretManager
6.5.2
dotnet add package CSharpEssentials.GcpSecretManager --version 6.5.2
NuGet\Install-Package CSharpEssentials.GcpSecretManager -Version 6.5.2
<PackageReference Include="CSharpEssentials.GcpSecretManager" Version="6.5.2" />
<PackageVersion Include="CSharpEssentials.GcpSecretManager" Version="6.5.2" />
<PackageReference Include="CSharpEssentials.GcpSecretManager" />
paket add CSharpEssentials.GcpSecretManager --version 6.5.2
#r "nuget: CSharpEssentials.GcpSecretManager, 6.5.2"
#:package CSharpEssentials.GcpSecretManager@6.5.2
#addin nuget:?package=CSharpEssentials.GcpSecretManager&version=6.5.2
#tool nuget:?package=CSharpEssentials.GcpSecretManager&version=6.5.2
CSharpEssentials.GcpSecretManager
Integrates Google Cloud Secret Manager into the .NET Configuration system. Load secrets as standard IConfiguration values.
Features
- Configuration Integration: Secrets appear as standard config keys.
- Multi-Project: Load from multiple GCP projects.
- AppSettings Support: Configure via
appsettings.jsonor fluent API. - Batch Processing: Efficient retrieval with configurable batch sizes.
- Transient Retry: Listing and per-secret access are retried on transient gRPC failures (uses
CSharpEssentials.Resilience).
Installation
dotnet add package CSharpEssentials.GcpSecretManager
Usage
Setup via Code
using CSharpEssentials.GcpSecretManager; // ProjectSecretConfiguration
using CSharpEssentials.GcpSecretManager.Extensions; // AddGcpSecretManager
builder.Configuration.AddGcpSecretManager(options =>
{
options.AddProject(new ProjectSecretConfiguration
{
ProjectId = "my-gcp-project",
PrefixFilters = new[] { "MyApp__" }
});
});
string connectionString = builder.Configuration["MyApp:ConnectionStrings:Default"]!;
Secrets are loaded once, synchronously, when AddGcpSecretManager is called (ConfigurationManager builds the added source immediately); there is no reload. The client uses Application Default Credentials unless options.CredentialsPath points to a credentials file. At least one project is required, otherwise AddGcpSecretManager throws ArgumentException.
ProjectSecretConfiguration:
| Property | Notes |
|---|---|
ProjectId |
Required. |
Region |
Optional. Reads regional secrets of projects/{id}/locations/{region} through the endpoint secretmanager.{region}.rep.googleapis.com. |
PrefixFilters |
Load only secrets whose id starts with one of these prefixes (case-sensitive). |
SecretIds |
Load these secrets by id, in addition to the prefix matches. With neither PrefixFilters nor SecretIds, every secret of the project is loaded. |
RawSecretIds, RawSecretPrefixes |
Secrets that are stored as one string and not parsed as JSON (see below). |
SecretManagerConfigurationOptions also has BatchSize (secrets read in parallel per project, default 10) and PageSize (secrets per list request, default 300). The latest version of every secret is read. When several projects or secrets produce the same key, the first one wins (projects in the order you added them).
Logging
Configuration providers are built before dependency injection exists, so the provider does not
resolve a logger on its own and writes nothing to the console by default. Pass an ILoggerFactory
to get diagnostics (per-secret progress at Debug, failures at Error):
using CSharpEssentials.GcpSecretManager;
using CSharpEssentials.GcpSecretManager.Extensions;
using ILoggerFactory loggerFactory = LoggerFactory.Create(b => b.AddConsole());
builder.Configuration.AddGcpSecretManager(options =>
{
options.LoggerFactory = loggerFactory;
options.AddProject(new ProjectSecretConfiguration { ProjectId = "my-gcp-project" });
});
SecretManagerConfigurationOptions is a sealed record; CredentialsPath, Loader, LoggerFactory
and Projects are settable and AddProject returns the options for chaining.
Retries
Listing a project's secrets and accessing each secret version use CSharpEssentials.Resilience
(RetryIfFailed with a shouldRetry predicate). Only ResourceExhausted and Unavailable are
retried: 3 retries with exponential backoff (2s, 4s, 8s). Any other status, such as
PermissionDenied or NotFound, fails immediately. When retries are exhausted the original
RpcException is logged once at Error: a listing failure skips that project, an access failure
skips that secret, and loading continues.
Setup via AppSettings
{
"GoogleSecretManager": {
"Projects": [
{ "ProjectId": "my-project", "PrefixFilters": ["Prod__"] }
]
}
}
using CSharpEssentials.GcpSecretManager.Extensions;
builder.Configuration.AddGcpSecretManager();
AddGcpSecretManager() without a callback reads the projects from the GoogleSecretManager section; it throws InvalidOperationException when the section, its projects or a ProjectId is missing. With a callback the section is not read; set options.LoadFromAppSettings = true to read it too, and options.ConfigurationSectionName to use another section. The section is read from the sources added before it, so call AddGcpSecretManager after appsettings.json (the default builder.Configuration already has it). Region, SecretIds, RawSecretIds and RawSecretPrefixes can be set in the section too.
Key Mapping
GCP secrets use underscores; .NET config uses colons:
- GCP:
MyApp__ConnectionStrings__Default - .NET:
MyApp:ConnectionStrings:Default
The secret id has every __ replaced by :. To use another rule or another selection of secrets, implement ISecretManagerConfigurationLoader (GetKey(Secret), GetKey(string), ShouldLoadSecret(Secret, ProjectSecretConfiguration), namespace CSharpEssentials.GcpSecretManager.Configuration) and assign it to options.Loader.
JSON Secrets
A secret whose value is JSON is also flattened into configuration keys. The key of the secret keeps the raw text, and every value below it gets a child key, with : between object names and array indexes:
Secret MyApp__Database |
Keys |
|---|---|
{"Host":"db","Ports":[5432,5433]} |
MyApp:Database (the raw JSON), MyApp:Database:Host = db, MyApp:Database:Ports:0 = 5432, MyApp:Database:Ports:1 = 5433 |
Bind the section as usual (builder.Configuration.GetSection("MyApp:Database").Get<DatabaseOptions>()). A value that is not valid JSON is kept as a plain string. List the secret in RawSecretIds, or by prefix in RawSecretPrefixes, to keep a JSON text (a certificate, a service account file) as one value without child keys.
| Product | Versions 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 was computed. 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 is compatible. 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 is compatible. 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. net11.0 is compatible. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- CSharpEssentials.Core (>= 6.5.2)
- CSharpEssentials.Resilience (>= 6.5.2)
- Google.Cloud.SecretManager.V1 (>= 2.6.0)
- Microsoft.Extensions.Configuration (>= 9.0.4)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.4)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.4)
- Polly.Core (>= 8.0.0 && < 9.0.0)
- System.Text.Json (>= 9.0.4)
-
net10.0
- CSharpEssentials.Core (>= 6.5.2)
- CSharpEssentials.Resilience (>= 6.5.2)
- Google.Cloud.SecretManager.V1 (>= 2.6.0)
- Microsoft.Extensions.Configuration (>= 9.0.4)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.4)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.4)
- Polly.Core (>= 8.0.0 && < 9.0.0)
-
net11.0
- CSharpEssentials.Core (>= 6.5.2)
- CSharpEssentials.Resilience (>= 6.5.2)
- Google.Cloud.SecretManager.V1 (>= 2.6.0)
- Microsoft.Extensions.Configuration (>= 9.0.4)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.4)
- Polly.Core (>= 8.0.0 && < 9.0.0)
-
net9.0
- CSharpEssentials.Core (>= 6.5.2)
- CSharpEssentials.Resilience (>= 6.5.2)
- Google.Cloud.SecretManager.V1 (>= 2.6.0)
- Microsoft.Extensions.Configuration (>= 9.0.4)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.4)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.4)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.4)
- Polly.Core (>= 8.0.0 && < 9.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.5.2 | 56 | 10/10/2026 |
| 6.5.1 | 52 | 10/10/2026 |
| 6.5.0 | 57 | 10/9/2026 |
| 6.4.0 | 66 | 10/9/2026 |
| 6.3.0 | 74 | 10/8/2026 |
| 6.2.0 | 94 | 10/8/2026 |
| 6.1.0 | 96 | 10/7/2026 |
| 6.0.0 | 93 | 10/7/2026 |
| 5.2.1 | 99 | 10/7/2026 |
| 5.2.0 | 96 | 10/7/2026 |
| 5.1.0 | 91 | 10/7/2026 |
| 5.0.0 | 92 | 10/6/2026 |
| 4.1.0 | 96 | 10/6/2026 |
| 4.0.0 | 94 | 10/5/2026 |
| 3.2.3 | 197 | 5/31/2026 |
| 3.2.2 | 131 | 5/31/2026 |
| 3.2.1 | 126 | 5/31/2026 |
| 3.2.0 | 124 | 5/30/2026 |
| 3.1.0 | 138 | 5/27/2026 |
| 3.0.8 | 123 | 5/20/2026 |