{"id":21449335,"url":"https://github.com/kralizek/awssecretsmanagerconfigurationextensions","last_synced_at":"2026-04-29T13:01:57.906Z","repository":{"id":31951424,"uuid":"129538387","full_name":"Kralizek/AWSSecretsManagerConfigurationExtensions","owner":"Kralizek","description":"This repository contains a provider for Microsoft.Extensions.Configuration that retrieves secrets stored in AWS Secrets Manager.","archived":false,"fork":false,"pushed_at":"2025-02-02T16:35:44.000Z","size":108,"stargazers_count":241,"open_issues_count":18,"forks_count":48,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-06T05:04:39.259Z","etag":null,"topics":["aspnet-core","aws","aws-secrets-manager","dotnet-standard"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kralizek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-14T17:17:49.000Z","updated_at":"2025-04-02T11:59:13.000Z","dependencies_parsed_at":"2025-02-22T16:44:45.604Z","dependency_job_id":null,"html_url":"https://github.com/Kralizek/AWSSecretsManagerConfigurationExtensions","commit_stats":{"total_commits":53,"total_committers":17,"mean_commits":"3.1176470588235294","dds":"0.41509433962264153","last_synced_commit":"8a2758ba81722cd09d81de461ec4ce97838a7746"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kralizek%2FAWSSecretsManagerConfigurationExtensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kralizek%2FAWSSecretsManagerConfigurationExtensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kralizek%2FAWSSecretsManagerConfigurationExtensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kralizek%2FAWSSecretsManagerConfigurationExtensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kralizek","download_url":"https://codeload.github.com/Kralizek/AWSSecretsManagerConfigurationExtensions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248688542,"owners_count":21145763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnet-core","aws","aws-secrets-manager","dotnet-standard"],"created_at":"2024-11-23T03:19:47.487Z","updated_at":"2026-04-29T13:01:57.899Z","avatar_url":"https://github.com/Kralizek.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kralizek.Extensions.Configuration.AWSSecretsManager\n\n[![NuGet](https://img.shields.io/nuget/v/Kralizek.Extensions.Configuration.AWSSecretsManager.svg)](https://www.nuget.org/packages/Kralizek.Extensions.Configuration.AWSSecretsManager)\n[![Build status](https://github.com/Kralizek/AWSSecretsManagerConfigurationExtensions/actions/workflows/ci.yml/badge.svg)](https://github.com/Kralizek/AWSSecretsManagerConfigurationExtensions/actions/workflows/ci.yml)\n\nAWS Secrets Manager configuration provider for `Microsoft.Extensions.Configuration`. Load secrets directly into your .NET configuration pipeline.\n\n## Installation\n\n```bash\ndotnet add package Kralizek.Extensions.Configuration.AWSSecretsManager\n```\n\n## Choosing a Mode\n\nThe library provides three explicit loading modes. Pick the one that matches your access pattern:\n\n| Mode | Extension method | AWS API | Best for |\n|---|---|---|---|\n| **Discovery** | `AddSecretsManagerDiscovery` | `ListSecrets` + `BatchGetSecretValue` | Load all secrets in an account/region |\n| **KnownSecrets** | `AddSecretsManagerKnownSecrets` | `BatchGetSecretValue` | Load a fixed set of known secrets |\n| **KnownSecret** | `AddSecretsManagerKnownSecret` | `GetSecretValue` | Load exactly one secret |\n\n---\n\n## Discovery Mode\n\nDiscover and load all secrets returned by `ListSecrets`, then batch-fetch their values.\n\n```csharp\n// Minimal — use default AWS credentials and region\nbuilder.AddSecretsManagerDiscovery();\n\n// With AWSOptions (region, profile, credentials)\nvar awsOptions = new AWSOptions { Region = Amazon.RegionEndpoint.EUWest1 };\nbuilder.AddSecretsManagerDiscovery(awsOptions);\n\n// With a pre-built client\nvar client = new AmazonSecretsManagerClient(RegionEndpoint.EUWest1);\nbuilder.AddSecretsManagerDiscovery(client);\n```\n\n### Filtering discovered secrets\n\nUse `SecretFilter` to skip secrets you don't need, or `ListSecretsFilters` to apply server-side filters:\n\n```csharp\nbuilder.AddSecretsManagerDiscovery(options =\u003e\n{\n    // Client-side filter\n    options.SecretFilter = entry =\u003e entry.Name.StartsWith(\"myapp/\");\n\n    // Server-side filters (reduce ListSecrets results at the API level)\n    options.ListSecretsFilters.Add(new Filter\n    {\n        Key = FilterNameStringType.Name,\n        Values = new List\u003cstring\u003e { \"myapp/\" }\n    });\n});\n```\n\n### Key customization\n\nControl how secret names and JSON property paths become configuration keys:\n\n```csharp\nbuilder.AddSecretsManagerDiscovery(options =\u003e\n{\n    options.KeyGenerator = (entry, key) =\u003e key.Replace(\"/\", \":\");\n});\n```\n\n### Batch vs. individual fetch\n\nDiscovery mode uses `BatchGetSecretValue` by default. To fall back to one `GetSecretValue` call per secret:\n\n```csharp\nbuilder.AddSecretsManagerDiscovery(options =\u003e\n{\n    options.UseBatchFetch = false;\n});\n```\n\n---\n\n## KnownSecrets Mode\n\nFetch a fixed list of secrets by ARN or name using `BatchGetSecretValue`. No `ListSecrets` call is made.\n\n```csharp\nbuilder.AddSecretsManagerKnownSecrets(new[]\n{\n    \"MySecretFullARN-abcxyz\",\n    \"MySecretPartialARN\",\n    \"MySecretUniqueName\"\n});\n```\n\nWith `AWSOptions` or a custom client:\n\n```csharp\nbuilder.AddSecretsManagerKnownSecrets(awsOptions, new[] { \"my-app/db\", \"my-app/api-key\" });\nbuilder.AddSecretsManagerKnownSecrets(client,     new[] { \"my-app/db\", \"my-app/api-key\" });\n```\n\n---\n\n## KnownSecret Mode\n\nLoad exactly one secret by ARN or name using `GetSecretValue`. No `ListSecrets` or batch call is made.\n\n```csharp\nbuilder.AddSecretsManagerKnownSecret(\"my-app/prod\");\n\n// With AWSOptions or a custom client\nbuilder.AddSecretsManagerKnownSecret(awsOptions, \"my-app/prod\");\nbuilder.AddSecretsManagerKnownSecret(client,     \"my-app/prod\");\n```\n\n---\n\n## Multiple Registrations\n\nYou can call any combination of the three methods multiple times on the same builder. Each registration adds an independent provider that loads independently. This is useful when you need to combine different access patterns — for example, loading a shared set of secrets by discovery alongside a single high-privilege secret fetched directly:\n\n```csharp\nbuilder\n    .AddSecretsManagerDiscovery(options =\u003e\n    {\n        options.SecretFilter = entry =\u003e entry.Name.StartsWith(\"myapp/shared/\");\n    })\n    .AddSecretsManagerKnownSecret(\"myapp/high-privilege-secret\")\n    .AddSecretsManagerKnownSecrets(new[] { \"myapp/db\", \"myapp/api-key\" });\n```\n\nLater registrations take precedence over earlier ones when the same configuration key appears in more than one provider (standard `Microsoft.Extensions.Configuration` behaviour). Within a single provider, use `DuplicateKeyHandling` to control conflicts between secrets resolved by that provider.\n\n---\n\n## Duplicate Key Handling\n\nWhen two secrets produce the same configuration key, control the conflict resolution:\n\n```csharp\nbuilder.AddSecretsManagerDiscovery(options =\u003e\n{\n    options.DuplicateKeyHandling = DuplicateKeyHandling.LastWins;  // default\n    // options.DuplicateKeyHandling = DuplicateKeyHandling.FirstWins;\n    // options.DuplicateKeyHandling = DuplicateKeyHandling.Throw;\n});\n```\n\n---\n\n## Reload / Polling\n\nRe-fetch secrets on a schedule:\n\n```csharp\nbuilder.AddSecretsManagerDiscovery(options =\u003e\n{\n    options.ReloadInterval = TimeSpan.FromMinutes(5);\n});\n```\n\n---\n\n## Bootstrap Logging\n\nAttach a logger during startup before the DI container is built:\n\n```csharp\nusing var loggerFactory = LoggerFactory.Create(b =\u003e b.AddConsole());\n\nbuilder.AddSecretsManagerDiscovery(options =\u003e\n{\n    options.UseBootstrapLogging(loggerFactory);\n});\n```\n\n---\n\n## JSON Secret Flattening\n\nSecrets whose value is a JSON object are automatically flattened into configuration key/value pairs using `:` as the separator, rooted at the secret's name.\n\nFor example, a secret named `myapp/database` with value `{\"Host\":\"db.example.com\",\"Port\":\"5432\"}` produces:\n\n```\nmyapp/database:Host = db.example.com\nmyapp/database:Port = 5432\n```\n\n---\n\n## No Caching\n\nThe provider fetches values from AWS Secrets Manager on each `Load()` call and on every configured reload. There is no in-memory cache layer between reloads — secrets are not re-fetched until the next explicit load or scheduled reload fires.\n\n---\n\n## Amazon Elastic Kubernetes Service (EKS)\n\nIn order to authenticate requests to AWS Secrets Manager a pod needs to use an IAM role that grants access to your secrets. Amazon introduced [IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) to make this possible without third-party solutions.\n\nThis feature requires an additional package loaded by reflection:\n\n```bash\ndotnet add package AWSSDK.SecurityToken\n```\n\n---\n\n## Migration from earlier versions\n\nSee [MIGRATION.md](MIGRATION.md) for the list of breaking changes.\n\n---\n\n## Mentions by the community\n\n* [Secure secrets storage for ASP.NET Core with AWS Secrets Manager (Part 1)](https://andrewlock.net/secure-secrets-storage-for-asp-net-core-with-aws-secrets-manager-part-1/) by Andrew Lock\n* [Secure secrets storage for ASP.NET Core with AWS Secrets Manager (Part 2)](https://andrewlock.net/secure-secrets-storage-for-asp-net-core-with-aws-secrets-manager-part-2/) by Andrew Lock\n* [Useful tools to manage your application's secrets](https://raygun.com/blog/manage-application-secrets/) by Jerrie Pelser\n* [Storing secrets CORRECTLY in .NET using AWS Secrets Manager](https://www.youtube.com/watch?v=BGW4FnEB-CM) by [Nick Chapsas](https://github.com/Elfocrash)\n* [Effortless Secret Management in .NET Using AWS Secrets Manager](https://www.youtube.com/watch?v=hDVdLNJfaNU) by [Milan Jovanović](https://github.com/m-jovanovic)\n* [Cloud Fundamentals: AWS Services for C# Developers](https://dometrain.com/course/cloud-fundamentals-aws-services-for-c-developers/) by [Nick Chapsas](https://github.com/Elfocrash)\n\n## Stargazers over time\n\n[![Stargazers over time](https://starchart.cc/Kralizek/AWSSecretsManagerConfigurationExtensions.svg)](https://starchart.cc/Kralizek/AWSSecretsManagerConfigurationExtensions)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkralizek%2Fawssecretsmanagerconfigurationextensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkralizek%2Fawssecretsmanagerconfigurationextensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkralizek%2Fawssecretsmanagerconfigurationextensions/lists"}