Correct way to use KMS Decrypt in Cognito Custom Email Sender Lambda

335 Views Asked by At

I have an AWS Cognito User configured with a Custom Email Sender as follows:

resource "aws_kms_key" "cognito-send-mails" {
  description             = "This key is used to decrypt Cognito codes for CustomEmailSender lambda"
  deletion_window_in_days = 10
  enable_key_rotation     = true
}

resource "aws_cognito_user_pool" "users" {
  # ...
  lambda_config {
    kms_key_id          = aws_kms_key.cognito-send-mails.arn

    custom_email_sender {
      lambda_arn     = aws_lambda_function.cognito-send-emails.arn
      lambda_version = "V1_0"
    }
  }
}

resource "aws_lambda_function" "cognito-send-emails" {
  # ...
  environment {
    variables = {
      KEY_ID               = aws_kms_key.cognito-send-mails.arn
    }
  }
}

resource "aws_lambda_permission" "cognito-send-mails" {
  statement_id   = "AllowExecutionFromCognitoUserPool"
  action         = "lambda:InvokeFunction"
  function_name  = aws_lambda_function.cognito-send-emails.function_name
  principal      = "cognito-idp.amazonaws.com"
  source_account = data.aws_caller_identity.current.account_id
}

resource "aws_iam_role_policy" "cognito-send-mails-kms" {
  name = "cognito-${local.deployment-name}-send-emails-lambda-kms"
  role = aws_iam_role.lambda_exec_role.id

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "kms:Decrypt"
        ],
        "Resource": "${aws_kms_key.cognito-send-mails.arn}"
    }
  ]
}
EOF
}

I successfully got triggered with:

{
  "callerContext": {
    "awsSdkVersion": "aws-sdk-unknown-unknown",
    "clientId": "..."
  },
  "region": "...",
  "request": {
    "clientMetadata": null,
    "code": "AYADe1...ANY=",
    "type": "customEmailSenderRequestV1",
    "userAttributes": {
      "cognito:email_alias": "...",
      "cognito:user_status": "UNCONFIRMED",
      "email": "...",
      "email_verified": "false",
      "name": "...",
      "sub": "..."
    }
  },
  "triggerSource": "CustomEmailSender_SignUp",
  "userName": "...",
  "userPoolId": "...",
  "version": "1"
}

My aim is to decipher code to build the email.

I'm forced to use AWS KMS directly since I only have access to an API-based generated library (I use amazonka, in Haskell).

In the end, I'm calling AWS KMS API with:

Decrypt {
  encryptionAlgorithm = null,
  encryptionContext = null,
  grantTokens = null,
  keyId = "arn:aws:kms:***:***:key/***",
  ciphertextBlob = "AYADe1...ANY="
}

However, I encounter the following error:

ServiceError {
  abbrev = "KMS",
  status = Status {statusCode = 400, statusMessage = "Bad Request"},
  headers = [
    ("x-amzn-RequestId","***"),
    ("Cache-Control","no-cache, no-store, must-revalidate, private"),
    ("Expires","0"),
    ("Pragma","no-cache"),
    ("Date","***"),
    ("Content-Type","application/x-amz-json-1.1"),
    ("Content-Length","39")
  ],
  code = "InvalidCiphertext",
  message = null,
  requestId = "***"
}

I also tried to base64 decode/encode again and base64 encode again code, but I have the same error code.

What the correct to proceed, only with the KMS API?

0

There are 0 best solutions below