GM.Secrets
1.0.0
dotnet add package GM.Secrets --version 1.0.0
NuGet\Install-Package GM.Secrets -Version 1.0.0
<PackageReference Include="GM.Secrets" Version="1.0.0" />
<PackageVersion Include="GM.Secrets" Version="1.0.0" />
<PackageReference Include="GM.Secrets" />
paket add GM.Secrets --version 1.0.0
#r "nuget: GM.Secrets, 1.0.0"
#:package GM.Secrets@1.0.0
#addin nuget:?package=GM.Secrets&version=1.0.0
#tool nuget:?package=GM.Secrets&version=1.0.0
GM.Secrets
A provider-agnostic secrets abstraction for the GM.* ecosystem. Your code depends on one
interface — ISecretsService — and the backend (environment variables, configuration, and, as
follow-on packages, Azure Key Vault / AWS Secrets Manager / HashiCorp Vault) is chosen by
configuration. Remote lookups are cached with a TTL via GM.Caching, so reads are cheap and
rotation happens automatically when the cache entry expires.
GM.Secrets— the coreISecretsService/ISecretsProvider, caching, typed & required access, and config-driven provider selection. Depends only onGM.Caching.GM.Secrets.Environment— reads environment variables (with prefix + name normalization).GM.Secrets.Configuration— reads fromIConfiguration(appsettings, user secrets, any source).
Install
dotnet add package GM.Secrets
dotnet add package GM.Secrets.Environment # and/or
dotnet add package GM.Secrets.Configuration
Register
builder.Services.AddGMCaching(); // optional — enables TTL caching / rotation of secret reads
// Register the providers you want available…
builder.Services.AddGMEnvironmentSecrets(builder.Configuration);
builder.Services.AddGMConfigurationSecrets(builder.Configuration);
// …and select the active one (+ options) from configuration.
builder.Services.AddGMSecrets(builder.Configuration);
{
"Secrets": {
"Provider": "Environment", // which backend wins
"CacheDuration": "00:05:00", // 0 disables caching
"Environment": { "Prefix": "MYAPP_" },
"Configuration": { "SectionName": "SecretValues" }
}
}
Switching backends (dev → prod, Environment → Key Vault) is a config change — no code change — as long as the provider package is registered.
Use
public sealed class PaymentClient(ISecretsService secrets)
{
public async Task ChargeAsync(...)
{
// Required: throws SecretNotFoundException if absent (fail fast at the edge).
var apiKey = await secrets.GetRequiredSecretAsync("Payments:ApiKey");
// Optional: null when absent.
var webhookSecret = await secrets.GetSecretAsync("Payments:WebhookSecret");
// Typed: a structured secret stored as JSON.
var creds = await secrets.GetSecretAsync<DbCredentials>("Db:Credentials");
// …use them; never log a secret value.
}
}
Values returned are sensitive — pass them straight to the consumer (a connection string, an SDK
credential); don't log them. SecretNotFoundException and error messages carry only the secret
name, never a value.
Add a provider
Implement ISecretsProvider and register it as a keyed singleton under a provider name — the
core selector resolves whichever Secrets:Provider names:
public sealed class VaultSecretsProvider : ISecretsProvider
{
public string Name => "Vault";
public Task<string?> GetSecretAsync(string name, CancellationToken ct = default) => /* fetch */;
}
services.AddKeyedSingleton<ISecretsProvider, VaultSecretsProvider>("Vault");
Follow-up provider packages (flagged, not built)
Cloud backends slot in behind the same ISecretsProvider — deliberately left as follow-ups so each
ships tested against its SDK:
GM.Secrets.AzureKeyVault—Azure.Security.KeyVault.Secrets+DefaultAzureCredential.GM.Secrets.AwsSecretsManager—AWSSDK.SecretsManager.GM.Secrets.Vault— HashiCorp Vault viaVaultSharp.
A configuration-provider integration (surface secrets through IConfiguration at startup) and using
GM.Secrets to supply runtime overrides elsewhere in the stack (e.g. rate-limit policy values) are
natural extensions.
Samples
GM.Secrets.Samples — a runnable API that consumes secrets without ever exposing them.
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- GM.Caching (>= 1.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on GM.Secrets:
| Package | Downloads |
|---|---|
|
GM.Secrets.Environment
Environment-variable secrets provider for GM.Secrets — resolves secrets from environment variables with a configurable prefix and name transform (e.g. "Db:Password" → "DB_PASSWORD"). Zero dependencies; ideal for containers and 12-factor apps. Register with AddGMEnvironmentSecrets() and select via Secrets:Provider = "Environment". |
|
|
GM.Secrets.Configuration
Configuration-backed secrets provider for GM.Secrets — resolves secrets from IConfiguration (appsettings, user secrets, or any configuration source), optionally under a section. Handy for development and for apps that already surface secrets through configuration. Register with AddGMConfigurationSecrets() and select via Secrets:Provider = "Configuration". |
|
|
GM.KYC.Identomat
Identomat provider for GM.KYC. Implements the IKycProvider SPI against Identomat's external API (POST /begin to start a hosted-widget session, /upload-file to attach normalized documents, /result to read the decision) and maps Identomat's approved/rejected/live/similarity vocabulary onto the GM.KYC.Domain status set. The API key (companyKey) is pulled from GM.Secrets — never hardcoded. Inbound webhook callbacks are signature-verified and deduped via GM.Idempotency (at-least-once delivery). Register with AddGMKyc().AddIdentomat(). |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 98 | 8/5/2026 |