Reputation: 327
I am trying to decrypt a parameter stored on SSM that is encrypted with a user managed KMS key, which I just created.
EncryptionContext
. But when I created the key and the parameter I did not used a context. I also checked on CloudTrail and there's no information about context. And I also didn't find any place to declare a context when creating a new parameter.This Lambda is being executed with the correct permissions to Decrypt with the key and to Read from the SSM parameter store.
I am sure the parameter is fetched correctly, because I am able to retrieve the stored parameter if I do not encrypt it with the KMS key.
I also tryied using another library base64-js to encrypt the string to Uint8Array
, but the result is the same.
This is the sample code:
import { DecryptCommand, KMSClient } from '@aws-sdk/client-kms';
import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm';
const kmsClient = new KMSClient({ region: process.env.REGION });
const ssmClient = new SSMClient({ region: process.env.REGION });
try {
const response = await ssmClient.send(new GetParameterCommand({
Name: `/path/to/param`
}));
// Value below verified without KMS key
const sureItIsValid = response.Parameter?.Value as string
// Obtained the same result for buff using base64-js lib
const buff: Uint8Array = Buffer.from(sureItIsValid, 'base64');
const command = new DecryptCommand({
CiphertextBlob: buff,
// The KeyId was also verified using the alias
KeyId: 'arn:aws:kms:<REGION>:...',
});
const secrets = await kmsClient.send(command);
console.error('result');
console.log(secrets.Plaintext?.toString());
} catch (error) {
console.error('error');
console.error(JSON.stringify(error));
}
And I get:
ERROR error
ERROR {"name":"InvalidCiphertextException","$fault":"client","$metadata":{"httpStatusCode":400,"requestId":"the-request-id","attempts":1,"totalRetryDelay":0},"__type":"InvalidCiphertextException","message":"UnknownError"}
Upvotes: 0
Views: 1965
Reputation: 25639
Add WithDecryption: true to your GetParameterCommand
. SSM will call KMS to decrypt* the SecretString
paramter and return the plaintext to us in Parameter.Value
:
const command = new GetParameterCommand({
Name: '/path/to/param',
WithDecryption: true,
});
* You are using the CDK to handle your Lambda permissions, so the following will work:
param.grantRead(func); // let your Lambda function read the SSM Parameter
key.grantDecrypt(func); // let your Lambda Function decrypt the SSM Parameter
Upvotes: 3