AWS Contact Center

Creating a secure IVR solution with Amazon Connect

Join us for AWS Contact Center Day, a free virtual event where you’ll learn about the future of customer service, how machine learning can optimize customer and agent experiences—and more. Register now »

Creating a secure IVR solution with Amazon Connect

The contact flows in Amazon Connect can be used to create dynamic Interactive Voice Response (IVR) solutions. With Amazon Connect, organizations can gather appropriate personal information to customize the customer experience when they interact with their IVR. The personal information can include social security numbers, credit card information, and addresses. Because of compliance reasons, sensitive personal information must be encrypted in motion and when stored. Always encrypt personal information.

This blog post shows you how customers can use the Store customer input block in Amazon Connect to gather sensitive personal information, and automatically encrypt the data by using the customer’s own supplied encryption keys. This feature allows the customer to comply with encryption requirements.

To achieve this, Amazon Connect uses the AWS Encryption Software Development KIT (SDK) to encrypt customer provided data. The SDK uses an envelope encryption approach. This protects both the raw data and the data keys used to encrypt them. For more information about how the AWS Encryption SDK works, see Envelope Encryption.

This post shows the steps required to:

  1. Configure Amazon Connect to collect a credit card number. See Create an Amazon Connect instance if you need to create an instance.
  2. Encrypt the credit card digits.
  3. Send it to our backend AWS Lambda for decryption, using the customer supplied decryption key.

We will use the Amazon Connect contact flow shown in the following illustration:

Implementing the secure IVR

To implement our secure IVR, we must:

  1. Create new encryption and decryption keys, or import existing ones.
  2. Upload our public key to Amazon Connect to encrypt collected credit card digits.
  3. Securely store the decryption key and master key id into AWS parameter store
  4. Create an AWS Lambda function to decrypt the collected digits
  5. Create the contact flow described in the previous section.


To implement the secure IVR, make sure that AWS Command Line Interface (AWS CLI) is installed, configured and pointed to the same region as your Amazon Connect instance. To verify that you can run “aws configure” from your Terminal window and verify that your default region name parameter has the correct value.

The Amazon Connect customer input encryption feature is designed to use the organization’s supplied public key to encrypt data. This allows the organization to use its private key to decrypt the data for further processing. Using a private key known only to the organization helps preserve the privacy that an organization requires. An organization can use either an existing key pair or create a new one. When the key information is available, the process remains the same.

If you are using your existing keys for this exercise, skip to step 2 of this section.

Step 1: Create the encryption and decryption keys

We will be leveraging OpenSSL for this step. If you are using a macOS computer, OpenSSL should already be installed. For information about installing OpenSSL, see this OpenSSL site.

Let’s use Terminal and the OpenSSL command line encryption utility to generate a self-signed certificate and private key. We create the private key and certificate in a single step. As a result, two files are generated:

  • A private key file: blog.connect.private.key
  • A certificate file: blog.connect.certificate.pem

When you run the following command, you are providing the usual necessary certificate request information; such as, country/region name, organization name, etc.

$ openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout blog.connect.private.key -days 730 -out blog.connect.certificate.pem

Notice that we created a certificate valid for 2 years (730 days). It is important to remember that the certificate’s expiration date monitoring remains the responsibility of the organization.

Next, we extract the public key from the certificate file using the OpenSSL utility. The next command generates a file named blog.connect.public.key, which contains the encryption key that we need to upload to Amazon Connect.

$ openssl x509 -pubkey -noout -in blog.connect.certificate.pem > blog.connect.public.key

We now have three files to use for the next steps.

Step 2: Upload our public key to Amazon Connect.

In this step, we upload our encryption key, so Amazon Connect knows to use it when we want to encrypt customer input.

  1. Login to the AWS Management Console and choose Amazon Connect.
  2. Open your instance, and in the left pane, choose Contact Flows.
  3. Choose Add Key, and paste the content of your public key file blog.connect.public.key. You can use any text editor to open the file and copy its content.
  4. Choose Add Key to save the public key, as shown in the following example. You now have a key ID generated for your public key. Copy it and save it for later.

Step 3: Securely store the decryption private key and the key id into the AWS Parameter Store

This step helps to make sure that our decryption is stored securely. Moreover, the decryption is stored with traceability and access rights management using the power of IAM. By using this approach, we can manage the access to our private key by selectively granting access to processes and users. Also, it lets the system log every access of the private key for audit purposes.

To run the following commands, you must be an AWS user with access to AWS Systems Manager and the permissions to create parameters. Work with your AWS SysOps team to verify proper access.

The first command securely uploads our private key to AWS Systems Manager Parameter Store. This saves the key to a parameter named CONNECT_INPUT_DECRYPTION_KEY.

$ aws ssm put-parameter --type SecureString --name CONNECT_INPUT_DECRYPTION_KEY --description "Private key for decryption of Amazon Connect collected data" --value "$(<blog.connect.private.key)"

The second command uploads our key id to AWS Systems Manager Parameter Store. This saves the key to a parameter named CONNECT_INPUT_KEY_ID. Replace YOUR_KEY_ID with your actual value.  This was saved in the previous step.

$ aws ssm put-parameter --type SecureString --name CONNECT_INPUT_KEY_ID --description "Key Id for decryption of Amazon Connect collected data" --value YOUR_KEY_ID

To run the previous command, you must be an AWS user with access to AWS Systems Manager and the permissions to create parameters. Work with your AWS SysOps team to verify proper access.

The command uses the default key alias/aws/ssm to encrypt your private key. If you prefer to use a different  AWS KMS key for this, you could do so by adding the –key-id option to this command.

After you complete this step, you can then go to the Parameter Store in the AWS Systems Manager console. There, you should see the newly created parameters as shown in the following screenshot. If you do not see them, it is most like a permissions issue which can be fixed by reviewing the output on your terminal window.

Step 4: Use AWS CloudFormation to create the Lambda function for decryption

In this step, we use AWS CloudFormation to automatically create the IAM role and the AWS Lambda function. The function is used to perform the decryption of the credit card number.

Very Important Note: For the needs of this blog, this “Launch Stack” button below will only work in the us-west-2 AWS region. If you are running this in a different region, please download the template and modify it to work in a different region.

To create the Lambda function for decryption using the “Launch Stack” button, follow these steps:

  1. Login to your AWS console.
  2. Confirm that the AWS Region selected has the Amazon Connect service available.
  3. Click on the button below “Launch Stack”

  1. On the AWS CloudFormation page, modify the stack name if you prefer a different one.
  2. In the Parameters section, select the LambdaLanguage to use. The template supports Node.js and Python.
  3. Check the “I acknowledge that AWS CloudFormation might create IAM resources” since this template will create an IAM role.
  4. You can keep the other options as default.
  5. Create stack and wait for it to complete.

Now let’s make sure that our Amazon Connect instance has access to this newly created AWS Lambda Function

  1. In the Amazon Connect console, choose Contact Flows and scroll to the bottom of the page in the AWS Lambda section.
  2. On the Function drop-down menu, select the DecryptCustomerInputV2 function and click on “+Add Lambda Function”, as shown in the following screenshot:


Step 5: Create a contact flow to collect digits and encrypt them.

In this step, download the contact flow we will use from this location. Save it to a file. In the following steps, you will import your saved file and modify it so that Amazon Connect knows which key we use to encrypt the credit card number.

  1. Open the Amazon Connect console.
  2. Click on Overview, then choose Login as administrator.
  3. On the Routing menu on the left side, choose Contact Flows to show the list of contact flows.
  4. Click on Create Contact flow.
  5. From the drop-down menu next to the Save button on the right side, as shown in the following screenshot, choose Import flow. This loads the flow that was downloaded at the beginning of this step.

  1. After the import completes, choose the Store customer input block and enter the key ID that you created in step 2, and the content of your blog.connect.certificate.pem file, as shown in the following example:

  1. Next, let’s point our contact flow’s Invoke AWS Lambda function block to our DecryptCustomerInputV2 function.

  1. Save and publish the contact flow, as we are done with all changes.
  2. Attach the contact flow to your test phone number, as shown in the following example. For more information about setting up a phone number, see Claiming Phone Numbers.

  1. Dial the test phone number to go through the flow. After the call is completed, check the Amazon CloudWatch Logs to confirm the digits that we entered are encrypted and passed to our AWS Lambda function for decryption.


To confirm that the decryption works as expected, we also log the deciphered text. However, avoid doing this in a production environment to ensure that sensitive data is not leaked through the log files.

The following extracts show the information that is stored in both the Contact Flow logs and the AWS Lambda function logs.

Contact flow logs

Collected input

    "Results": "Ayadenknhgfpvcozupzr/iqsf8caxwababvhd3mty3j5chrvlxb1ymxpyy1rzxkaree3dnhqa08wsxqyuhjrry9hzkxzuwjqcdbpk1nlnjlsdlm1oumybxczdllzsstcdgd5thova1qwaxfiss9iretuzz09aaeaduftyxpvbknvbm5ly3qajgq0odkxzgu4ltazmgytngq5ni05mgfiltk1ytk5ytqwzgfioaianh5lx/iigksv8ikxnhacoc2bc49o4lghiszqqdub+es8pjtkvjj/ahliatpfhh8cbmd1i5a6pgkbb7n+cgl4le0naby23mnjopk2/7ha0cxz9xdihwdwmzemy8qrqnij5xsprtrltsjdcdgn4ehyiliaazbcu78ym3vqaropadq37hstuqefjb4lwc5ms5pywpr7kijovcurccxqc/sxllip9ekybsoxqe4axpl45u6vwybpilsti1mmorz87nzwyqec3z2qj05pn7wlkfjvczmybx7ndkpbgdcn3ab4r7lhq+17romfroiewjvrq/d4pruavib4pfqmnspylbmkpehlwsctecnm7up8o/m39eian7+ku1wkdg9/ytda9arly2xt+rwdc/z0ybc4napagifgzhjcav3dq+bqp4twys9rr9svvpqgmnbetdnauuxsa9i0d3m/m/w2yarrcblahvvvdm81dtksbhmydtwffdaf+jquzsnr9ptosp1+qiy+xfz1aizevq48c17adf7v4kmui6qq45y7xeowo0+jtwu5vhvhir3lrmojqhi/0ghnhht+oi7u9w4pdmincz9fik624w6i4ipkcpfojot5fgplgtsccyynmmudhmvwaqhuwt1odap9fxdgfnl4rmocisveeya69c39i0w4iuimtmwcaaaaaawaabaa49p96uphs8oqh5tvuez+bjqmk1/8effmf/ebqv////8aaaabkmkv3c4jybvlj5niaaaacxzlnolrqr8h5/12w0gixi+j2uc9sifosgmazzblajea2hjiojk/sfcolisjbcai6rw81cbte+icb0s5fc2abnsvmbo/sirj9fdn15sul8nhajactvvxcpgdhbbXXXXXcia7sixk756ot+iwadi30z9lwbzdiyy7zh7zvy=",
    "ContactId": "21d2414f-4df4-4610-b1fc-4ce0136aXXXX",
    "ContactFlowId": "arn:aws:connect:us-east-1:94686809XXXX:instance/5c3b3cd5-9b18-4b06-8205-4672dd02XXXX/contact-flow/65c3cc36-38b5-4cfd-b74d-bd4a5a5cXXXX",
    "ContactFlowModuleType": "StoreUserInput",
    "Timestamp": "2020-11-15T02:27:57.306Z"

AWS Lambda invocation

    "ContactId": "21d2414f-4df4-4610-b1fc-4ce0136aXXXX",
    "ContactFlowId": "arn:aws:connect:us-east-1:94686809XXXX:instance/5c3b3cd5-9b18-4b06-8205-4672dd02XXXX/contact-flow/65c3cc36-38b5-4cfd-b74d-bd4a5a5cXXXX",
    "ContactFlowModuleType": "InvokeExternalResource",
    "Timestamp": "2020-11-15T02:27:57.371Z",
    "ExternalResults": {
        "body": "4444444444444444",
        "statusCode": "200"
    "Parameters": {
        "FunctionArn": "arn:aws:lambda:us-east-1:94686809XXXX:function:DecryptCustomerInputV2",
        "Parameters": {
            "EncryptedCreditCard": "AYADeNKNhGFpVCozUpZr/Iqsf8cAXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREE3dnhqa08wSXQyUHJRRy9hZkxzUWJQcDBpK1NLNjlSdlM1OUMybXczdllZSStCdGd5THova1QwaXFISS9IREtuZz09AAEADUFtYXpvbkNvbm5lY3QAJGQ0ODkxZGU4LTAzMGYtNGQ5Ni05MGFiLTk1YTk5YTQwZGFiOAIANH5Lx/IIgKsV8IKXNHAcoc2bC49O4LGhisZqQdub+eS8Pjtkvjj/AhLiatpfHH8cBmD1i5a6pgKBB7n+cgl4LE0naby23MNJOPK2/7ha0CxZ9xDIhWDWMzemy8qrqniJ5xspRtrLTSJdcdGN4EHyILIAazbCu78YM3VQaRopaDq37HstuQEfJB4LWc5mS5pYWPr7kIjoVcurccXqc/sXLliP9eKyBSoxqE4AxpL45U6vWybpIlStI1mmoRz87NZwYqEC3z2Qj05Pn7wLKfJvCZMyBx7NDKPbGdcN3Ab4R7lhq+17roMfROiEWJvrQ/d4pRUaVib4pfQMNsPYlbMKpEhlwSCtecNm7UP8o/m39EIAn7+Ku1Wkdg9/yTdA9Arly2xt+RwdC/Z0yBC4NaPAGIFgZhjCAV3dQ+Bqp4TWys9rr9SVVpqgmnBEtDNaUUXSa9i0d3M/M/W2YaRRCbLahvvvDm81DTkSBhmydtWFFdaf+jQuzSNr9pTosP1+QiY+xFz1AIzEvQ48C17Adf7v4KMui6qQ45Y7XEOwo0+JtWu5vHvhIr3lRmOjQhi/0GhnhHt+oI7u9W4pDmiNCz9fiK624W6i4iPkCpfoJOt5fgpLgTsCCyyNMMUDhMVWaQHuwT1OdaP9fXDGfnl4RmoCISveEyA69c39i0W4iUImtMwCAAAAAAwAABAA49P96uPhs8OqH5tvUeZ+bjQmk1/8EffMf/Ebqv////8AAAABKmKV3C4JyBVlj5niAAAACXzLnolrQr8H5/12w0giXi+J2UC9SIFOSgMAZzBlAjEA2HjioJk/SFcOLISJBCAI6RW81CBTe+icb0s5Fc2ABNSVmbO/sIRj9fdN15sUL8NhAjACtvVXCPGDHbB9mkd5KZxBk7hVQcIaXXX="
        "TimeLimit": "8000"

AWS Lambda Logs

The value entered is 4444444444444444

In this case, the entered digits were 4444444444444444.


That’s it!

In this post we covered how you can use Amazon Connect’s Encryption feature to collect digits from a caller and encrypt them using your own supplied key pair. We have also covered how you can use AWS Systems Managers to securely store your decryption key and key id.

With this, you can now build a secured IVR using Amazon Connect.

Please let us know what you built with this.