Trying Out the New Lambda Durable Functions Feature "Durable Execution Data Encryption"
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).
For an overview of Lambda Durable Functions, see the following article.
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 outAllowLambdaServicePrincipal— Allows the Lambda service principal to use GenerateDataKey, Decrypt, and DescribeKey. Theaws:SourceAccountcondition restricts this to requests from your own accountAllowExecutionRoleDecrypt— Allows the Lambda function's execution role to Decrypt. This is required to decrypt the data key during replay and checkpoint readsAllowCallerDecrypt— Allows the caller of the GetDurableExecution API to Decrypt. This is required when retrieving execution data withIncludeExecutionDataenabled
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.