SecretConfiguration.AwsKms
is a third-party configuration provider compatible with the Microsoft.Extensions.Configuration
package. It facilitates the storage of secrets in encrypted form in configuration files.
Encryption and decryption is performed using AWS Key Management Service.
Application configuration, including secrets, are sometimes managed externally from outside the application, with solutions such as Hashicorp Vault or AWS Systems Manager Parameter Store.
The drawback of this approach is that the set of settings required by an application evolve as new versions of the application are released. This means a separate version control system has to be introduced, on top of the version control system already used for the application source code. This also increases the potential for error as two closely related systems have to be kept in sync at all times.
Storing configuration in source control along with the code that relies on it allows configuration and code to be versioned together.
However, secrets may never be stored in clear text. The SecretConfiguration.AwsKms
package makes it possible to store secrets in a repository in encrypted form, and decrypts them transparently at runtime.
The cryptographic material is managed by AWS through the KMS service. Encryption and decryption of secrets is managed by this service.
First create a key on AWS KMS, either using the console, or the command line.
It is recommended to use symmetric encryption as this will allow to encrypt values of up to 4kb with the default key spec.
Take note of the KMS ARN once the key is created, for example: arn:aws:kms:eu-west-1:123456789:key/11111111-0000-0000-0000-000000000000
.
Use the following command from the AWS CLI to create the ciphertext for the secret:
aws kms encrypt --cli-binary-format raw-in-base64-out --key-id "11111111-0000-0000-0000-000000000000" --plaintext "SECRET_TO_ENCRYPT"
The key-id
parameter should be replaced by the actual KMS key ID obtained in the previous step.
The output will look like:
{
"CiphertextBlob": "AQICAHhDR/VQh6Ap...rfyKsKCG2h6WVK8=",
"KeyId": "arn:aws:kms:eu-west-1:123456789:key/11111111-0000-0000-0000-000000000000",
"EncryptionAlgorithm": "SYMMETRIC_DEFAULT"
}
The CiphertextBlob
property in the response is the value that will be added to the encrypted configuration file.
Create a secrets.json
file. This file will be used to store encrypted secrets. For example, add this content:
{
"Database": {
"Password": "AQICAHhDR/VQh6Ap...rfyKsKCG2h6WVK8="
}
}
Replace the value with the ciphertext value obtained in the previous step.
string keyId = "arn:aws:kms:eu-west-1:123456789:key/11111111-0000-0000-0000-000000000000";
builder.Configuration.AddAwsKmsEncryptedConfiguration(
new AmazonKeyManagementServiceClient(),
keyId,
encryptedSource => encryptedSource
.SetBasePath(builder.Environment.ContentRootPath)
.AddJsonFile("secrets.json"));
This allows the encrypted configuration file (secrets.json
) to be decrypted during startup using the KMS service. The decrypted configuration settings are then merged with the rest of the configuration obtained from other sources (such as command line, environment variables, or clear text JSON configuration files).
The configuration keys provided through the KmsSecretConfigurationSource
are now available in their decrypted form throughout the application:
IConfiguration configuration;
string databasePassword = configuration["Database:Password"];
Copyright 2021 Flavien Charlon
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.