Secrets (KMS / Secrets Manager)
Wire an AWS KMS-backed secret protector and a Secrets Manager store, then envelope-encrypt and store values.
What you'll build
A host that registers ISecretProtector (KMS envelope encryption) and ISecretStore
(AWS Secrets Manager) from SquidStd.Secrets.Aws, then exercises protect/unprotect and
set/get/list.
Prerequisites
- .NET 10 SDK
dotnet add package SquidStd.Secrets.Aws- The live calls (steps 2–3) need a KMS + Secrets Manager endpoint. The sample is
compile-and-wire focused: it resolves the services without AWS and only runs the live calls
when
SQUIDSTD_RUN_AWS=1is set with LocalStack (or real AWS) reachable at the configured endpoint.
Steps
1. Register the KMS protector and Secrets Manager store
RegisterKmsSecretProtector and RegisterAwsSecretsManagerStore take the KMS key alias, the
secret name prefix, and the AWS endpoint - pointed here at a LocalStack ServiceUrl.
// Wire the KMS-backed protector and the Secrets Manager store against a LocalStack endpoint.
bootstrap.ConfigureServices(
container =>
{
// Core services are registered one by one here: RegisterCoreServices() would also add
// the default AES-GCM protector and file secret store, which must not compete with the
// KMS protector and AWS Secrets Manager store registered below.
container.RegisterDataSerializer();
container.RegisterEventBusService();
container.RegisterJobSystemService();
container.RegisterMainThreadDispatcherService();
container.RegisterTimerWheelService();
container.RegisterMetricsCollectionService();
container.RegisterKmsSecretProtector(
options =>
{
options.KeyId = "alias/app";
options.Aws = new()
{
Region = "us-east-1",
ServiceUrl = "http://localhost:4566"
};
}
);
container.RegisterAwsSecretsManagerStore(
options =>
{
options.NamePrefix = "myapp/";
options.Aws = new()
{
Region = "us-east-1",
ServiceUrl = "http://localhost:4566"
};
}
);
return container;
}
);
2. Envelope-encrypt a value
Protect requests a KMS data key, encrypts the payload with it, and wraps the encrypted data
key alongside the ciphertext; Unprotect reverses it.
// Envelope-encrypt a value with a KMS data key, then decrypt it back.
var protectedBytes = protector.Protect(Encoding.UTF8.GetBytes("api-token"));
var plaintext = protector.Unprotect(protectedBytes);
Console.WriteLine($"Unprotected: {Encoding.UTF8.GetString(plaintext)}");
3. Store, fetch and list secrets
ISecretStore reads and writes named secrets through Secrets Manager; ListNamesAsync streams
the names under the configured prefix.
// Store, fetch, and list secrets through the Secrets Manager store.
await store.SetAsync("db-password", "s3cr3t");
var password = await store.GetAsync("db-password");
Console.WriteLine($"db-password: {password}");
await foreach (var name in store.ListNamesAsync())
{
Console.WriteLine($"secret: {name}");
}
Run it
dotnet run --project samples/SquidStd.Samples.Secrets
# with the live calls:
SQUIDSTD_RUN_AWS=1 dotnet run --project samples/SquidStd.Samples.Secrets