31
loading...
This website collects cookies to deliver better user experience
kms:Decrypt
permission. {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BlockKMSDecryptForAllResources",
"Effect": "Deny",
"Action": [
"kms:Decrypt"
],
"Resource": "*"
}
]
}
provider:
kmsKeyArn: arn:aws:kms:us-east-1:XXXXXX:key/some-hash # KMS key arn which will be used for encryption for all functions
kmsKeyArn
on provider
level to be used by all functions or on per functions basis. It is used to encrypt your environment variables on AWS. Beware, that if you haven't encrypted your secrets with KMS, using for instance the AWS CLI, before deploying your function, the secrets get transported in plaintext. const AWS = require('aws-sdk');
AWS.config.update({ region: 'eu-west-1' });
const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
const encrypted = process.env['MY_SECRET_ENV'];
let decrypted;
function processEvent(event) {
// TODO handle the event here
}
exports.handler = async (event) => {
if (!decrypted) {
// Decrypt code should run once and variables stored outside of the
// function handler so that these are decrypted once per container
const kms = new AWS.KMS();
try {
const req = {
CiphertextBlob: Buffer.from(encrypted, 'base64'),
EncryptionContext: { LambdaFunctionName: functionName },
};
const data = await kms.decrypt(req).promise();
decrypted = data.Plaintext.toString('ascii');
} catch (err) {
console.log('Decrypt error:', err);
throw err;
}
}
processEvent(event);
};
SecureString
, or other parameters, from SSM with ${ssm:/path/to/secureparam}
inside your serverless.yml. To get a secret from Secrets Manager the syntax looks similar with ${ssm:/aws/reference/secretsmanager/secret_ID_in_Secrets_Manager}
. Be aware, that SSM SecureString
automatically gets decrypted and parsed if they export stringified JSON content. You can turn this off by, passing the raw
instruction into variables (${ssm(raw):/path/to/secureparam}
). You can even get a raw SSM parameter from another region with ${ssm(eu-west-1, raw):/path/to/secureparam}
. Unless you pass the raw
instruction your secrets get decrypted and stored in plaintext within your Lambda's environment variables. The only advantage to using purely KMS is that you manage your secrets in one central place. Not every developer needs to have access to the secrets to use them when working on one of your Lambdas. The problem remains, that the secrets get stored in environment variables. Therefore, they only change when a new deployment happens. Unless you use the raw
instruction your secrets get stored in plaintext, and if you use the raw
instructions you need to decrypt them within your Lambda with kms.decrypt()
. // Use this code snippet in your app.
// If you need more information about configurations or implementing the sample code, visit the AWS docs:
// https://aws.amazon.com/developers/getting-started/nodejs/
// Load the AWS SDK
var AWS = require('aws-sdk'),
region = "eu-west-1",
secretName = "test/abc",
secret,
decodedBinarySecret;
// Create a Secrets Manager client
var client = new AWS.SecretsManager({
region: region
});
// In this sample we only handle the specific exceptions for the 'GetSecretValue' API.
// See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
// We rethrow the exception by default.
client.getSecretValue({SecretId: secretName}, function(err, data) {
if (err) {
if (err.code === 'DecryptionFailureException')
// Secrets Manager can't decrypt the protected secret text using the provided KMS key.
// Deal with the exception here, and/or rethrow at your discretion.
throw err;
else if (err.code === 'InternalServiceErrorException')
// An error occurred on the server side.
// Deal with the exception here, and/or rethrow at your discretion.
throw err;
else if (err.code === 'InvalidParameterException')
// You provided an invalid value for a parameter.
// Deal with the exception here, and/or rethrow at your discretion.
throw err;
else if (err.code === 'InvalidRequestException')
// You provided a parameter value that is not valid for the current state of the resource.
// Deal with the exception here, and/or rethrow at your discretion.
throw err;
else if (err.code === 'ResourceNotFoundException')
// We can't find the resource that you asked for.
// Deal with the exception here, and/or rethrow at your discretion.
throw err;
}
else {
// Decrypts secret using the associated KMS CMK.
// Depending on whether the secret is a string or binary, one of these fields will be populated.
if ('SecretString' in data) {
secret = data.SecretString;
} else {
let buff = new Buffer(data.SecretBinary, 'base64');
decodedBinarySecret = buff.toString('ascii');
}
}
// Your code goes here.
});
31