Trying Out the New Lambda Durable Functions Feature "Durable Execution Data Encryption"

Trying Out the New Lambda Durable Functions Feature "Durable Execution Data Encryption"

AWS Lambda Durable Functions can now encrypt durable execution data with customer managed keys (CMK). I tried CMK setup, error behavior when a key is disabled, access control via IncludeExecutionData, and CloudTrail auditing.
2026.07.23

This page has been translated by machine translation. View original

Introduction

On July 22, 2026, it became possible to encrypt the durable execution data of AWS Lambda Durable Functions with a customer managed key (CMK).

https://aws.amazon.com/about-aws/whats-new/2026/07/durablefunctions-cmk/

For an overview of Lambda Durable Functions, see the following article.

https://dev.classmethod.jp/articles/aws-lambda-durable-functions-awsreinvent/

Here is a summary of the changes in this update.

Item Before (AWS owned key) New feature (CMK)
Encryption method Automatically encrypted with an AWS owned key A customer managed key can be specified
Key management Fully managed by AWS Users control the key policy, rotation, and disabling
Access control Always returns all data (cannot be controlled) The IncludeExecutionData parameter controls whether input/output data is returned
When the key is disabled Not possible (managed by AWS) No access to any data (including metadata, as of this verification)
CloudTrail audit No KMS events GenerateDataKey / Decrypt events are recorded
Additional cost None CMK storage $1/month + API charges (first 20,000 requests per month free)

Below, I verify everything in order, from configuration to auditing.

Verification Details

Verification Environment

Item Value
Region ap-northeast-1 (Tokyo)
Lambda runtime nodejs24.x
Function name durable-cmk-test
CMK alias/durable-cmk-test (symmetric encryption, single region)
Execution role durable-cmk-test-role
Verification date 2026-07-23

Creating the CMK and Key Policy

I created a symmetric encryption key to use for encrypting durable execution data.

aws kms create-key \
  --description "Durable Functions CMK test" \
  --key-usage ENCRYPT_DECRYPT \
  --key-spec SYMMETRIC_DEFAULT

aws kms create-alias \
  --alias-name alias/durable-cmk-test \
  --target-key-id EXAMPLE-KEY-ID

In the key policy, permissions are granted to the following four parties.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnableRootAccountAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "AllowLambdaServicePrincipal",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": [
        "kms:GenerateDataKey",
        "kms:Decrypt",
        "kms:DescribeKey"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        }
      }
    },
    {
      "Sid": "AllowExecutionRoleDecrypt",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/durable-cmk-test-role"
      },
      "Action": "kms:Decrypt",
      "Resource": "*"
    },
    {
      "Sid": "AllowCallerDecrypt",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/durable-cmk-test-user"
      },
      "Action": "kms:Decrypt",
      "Resource": "*"
    }
  ]
}

The role of each statement is as follows.

  • EnableRootAccountAccess — Allows the root account (including delegation of permissions via IAM policies within the account) to perform all operations on the key. This is a common setting to prevent the key from being locked out
  • AllowLambdaServicePrincipal — Allows the Lambda service principal to use GenerateDataKey, Decrypt, and DescribeKey. The aws:SourceAccount condition restricts this to requests from your own account
  • AllowExecutionRoleDecrypt — Allows the Lambda function's execution role to Decrypt. This is required to decrypt the data key during replay and checkpoint reads
  • AllowCallerDecrypt — Allows the caller of the GetDurableExecution API to Decrypt. This is required when retrieving execution data with IncludeExecutionData enabled

Configuring DurableConfig.KMSKeyArn

Following the official documentation, I set the CMK on an existing Durable Function using update-function-configuration. Because --durable-config replaces the entire DurableConfig object, the existing ExecutionTimeout and RetentionPeriodInDays must also be specified.

aws lambda update-function-configuration \
  --function-name durable-cmk-test \
  --durable-config '{
    "KMSKeyArn":"arn:aws:kms:ap-northeast-1:123456789012:key/EXAMPLE-KEY-ID",
    "ExecutionTimeout":3600,
    "RetentionPeriodInDays":7
  }'

In the output after configuration, you can confirm that KMSKeyArn has been added to DurableConfig.

Output of update-function-configuration
{
  "FunctionName": "durable-cmk-test",
  "State": "Active",
  "LastUpdateStatus": "Successful",
  "DurableConfig": {
    "KMSKeyArn": "arn:aws:kms:ap-northeast-1:123456789012:key/EXAMPLE-KEY-ID",
    "RetentionPeriodInDays": 7,
    "ExecutionTimeout": 3600
  }
}

Verifying Durable Execution with a CMK

After configuring the CMK, I published a version and started a durable execution with an asynchronous invocation.

aws lambda publish-version --function-name durable-cmk-test
aws lambda invoke \
  --function-name durable-cmk-test:2 \
  --invocation-type Event \
  --cli-binary-format raw-in-base64-out \
  --payload '{"orderId":"order-12345"}' \
  response.json

After the durable execution completes, retrieve the durable execution ARN with list-durable-executions-by-function.

aws lambda list-durable-executions-by-function \
  --function-name durable-cmk-test:2 \
  --statuses SUCCEEDED

Using the retrieved ARN, I checked the result with get-durable-execution.

DURABLE_EXECUTION_ARN="arn:aws:lambda:ap-northeast-1:123456789012:function:durable-cmk-test:2/durable-execution/EXAMPLE-EXECUTION-NAME/EXAMPLE-EXECUTION-ID"

aws lambda get-durable-execution \
  --durable-execution-arn "$DURABLE_EXECUTION_ARN" \
  --include-execution-data

I confirmed that the durable execution, which included 3 steps and a 10-second wait, completed successfully, and that DurableConfig.KMSKeyArn was included in the result.

Output of get-durable-execution
{
  "DurableExecutionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:durable-cmk-test:2/durable-execution/EXAMPLE-EXECUTION-NAME/EXAMPLE-EXECUTION-ID",
  "InputPayload": "{\"orderId\":\"order-12345\"}",
  "Result": "{\"orderId\":\"order-12345\",\"status\":\"completed\",\"steps\":[...]}",
  "Status": "SUCCEEDED",
  "StartTimestamp": "2026-07-23T10:13:58.463000+09:00",
  "EndTimestamp": "2026-07-23T10:14:10.524000+09:00",
  "Version": "2",
  "ExecutionDataIncluded": true,
  "DurableConfig": {
    "KMSKeyArn": "arn:aws:kms:ap-northeast-1:123456789012:key/EXAMPLE-KEY-ID",
    "RetentionPeriodInDays": 7,
    "ExecutionTimeout": 3600
  }
}

Checking the Error When the Key Is Disabled

I checked what happens to access to durable execution data when the CMK is disabled.

aws kms disable-key --key-id EXAMPLE-KEY-ID

When I ran get-durable-execution after disabling the key, an error was returned immediately.

An error occurred (KMSDisabledException) when calling the GetDurableExecution operation:
Lambda was unable to access your execution data because the KMS key used is disabled.
Check the KMS key configured in the function's durable config.
KMS Exception: DisabledException
KMS Message: arn:aws:kms:ap-northeast-1:123456789012:key/EXAMPLE-KEY-ID is disabled.

Even when I specified --no-include-execution-data to try to retrieve only metadata, the same KMSDisabledException occurred. According to the documentation, KMS is not called when IncludeExecutionData=false, but as of this verification the API itself returned an error (the service-side behavior may change in the future). In this verification, the data of durable executions that had completed successfully before the key was disabled also became inaccessible after disabling, with the same KMSDisabledException.

Comparing IncludeExecutionData

After re-enabling the key, I checked the difference in returned fields between --include-execution-data and --no-include-execution-data.

For get-durable-execution, the returned content changes as follows depending on the specified value.

Parameter Returned content
--include-execution-data InputPayload, Result, ExecutionDataIncluded=true, and all metadata
--no-include-execution-data Metadata only (Status, timestamps, Version, DurableConfig). No InputPayload/Result. ExecutionDataIncluded=false
Not specified (CLI default) Same behavior as --include-execution-data (the CLI default is true)

I also checked get-durable-execution-history in the same way.

Parameter Payload field
--include-execution-data JSON plaintext in each event's Payload + "Truncated": false
--no-include-execution-data Payload hidden, only "Truncated": true

When --no-include-execution-data was specified, no Decrypt event for the caller role was recorded in CloudTrail (see the table in the next section for details).

Checking KMS Events in CloudTrail

For durable executions using a CMK, the following KMS events are recorded in CloudTrail. These are the patterns observed in this verification (due to data key caching, they do not necessarily occur for every durable execution).

Event Caller Timing
GenerateDataKey AWSService (lambda.amazonaws.com) At the start of a durable execution (data key generation)
Decrypt AWSService (lambda.amazonaws.com) During processing of a durable execution (decrypting the data key)
Decrypt Execution role During replay/checkpoint reads
Decrypt Caller role During GetDurableExecution (IncludeExecutionData=true)
Decrypt (DisabledException) Caller role During GetDurableExecution after the key was disabled

The GenerateDataKey and Decrypt events for durable execution data include the following encryptionContext (it is not included in the DescribeKey event during key configuration).

{
  "aws:lambda:FunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:durable-cmk-test"
}

The execution role's Decrypt events include an inScopeOf field, in which the function that issued the credentials is recorded with a versioned ARN. This lets you trace which version of the function a Decrypt request came from.

Cost

This is the cost of using a CMK.

Item Price
CMK storage $1/month/key (prorated hourly, about $0.00137/hour)
KMS API requests First 20,000 per month free, $0.03 per 10,000 beyond that
Durable Functions CMK feature No additional charge
Actual cost of this verification Less than $0.01 (about 10 API requests in total)

No storage charge is incurred for keys in the pending deletion state (PendingDeletion). For pricing details, see the AWS KMS pricing page.

Summary

Lambda Durable Functions can now use a customer managed key (CMK) to encrypt durable execution data.

By using a CMK, you can handle key management, access control, and auditing of KMS operations through CloudTrail in line with your organization's requirements. This is useful when handling sensitive execution data or when you have requirements for managing and auditing encryption keys.

On the other hand, disabling the key or changing the key policy affects the execution of durable executions and access to their data. In this verification, the behavior of IncludeExecutionData=false when the key was disabled also differed from the documentation.

Considering the controllability of a CMK and the impact that key management has on the availability of durable execution data, please carefully consider adoption according to your requirements.

Share this article