View a markdown version of this page

加密 AWS Lambda 持久性执行数据 - AWS Lambda

加密 AWS Lambda 持久性执行数据

使用 AWS Lambda 持久性函数时,您可以构建可最长运行一年的高韧性、多步骤应用程序,并使用检查点在执行失败时通过重放已完成的作业恢复每个执行。

Lambda 始终会静态加密持久性执行数据。此外,您还可以在函数上配置自己的 AWS KMS 客户自主管理型密钥,以满足轮换控制、审计可见性或合规性需要。使用客户自主管理型密钥时,只有您授权的主体才能读取执行数据。

解密的工作原理

Lambda 持久性执行在其整个生命周期中均使用与启动时相同的 KMS 密钥。更改或移除函数上的密钥仅会影响更改后启动的执行。有关持久性执行在密钥不可用时的行为,请参阅当客户自主管理型密钥不可用时

客户托管式密钥产生标准 AWS KMS 费用。有关定价的详细信息,请参阅 AWS Key Management Service 定价

什么是加密?

当您在持久性函数上配置客户自主管理型密钥时,Lambda 会使用该密钥加密以下静态持久性执行数据:

  • 您在每个 Invoke 请求中传递的输入有效载荷。

  • CheckpointDurableExecution API 保留的检查点数据,包括步骤结果、步骤错误和链式调用输入。

  • 执行结果和错误。

  • 您通过 SendDurableExecutionCallbackSuccessSendDurableExecutionCallbackFailure 提交的回调结果和错误。

函数级别的密钥和持久性密钥是相互独立的

用于加密环境变量.zip 部署包SnapStart 快照的函数级别 KMSKeyArnDurableConfig 中用于加密持久性执行数据的 KMSKeyArn 是分开的。其中一个的设置不会作用于另一个。这两个密钥可以使用相同的 KMS 密钥,也可以使用不同的 KMS 密钥。

设置客户自主管理型密钥加密

为持久性函数设置客户自主管理型密钥加密包含三个步骤。按顺序完成以下步骤。

创建客户托管密钥

持久性函数支持函数所在相同 AWS 区域中的对称加密 KMS 密钥。不支持跨区域密钥。要创建对称客户自主管理型密钥,请按照《AWS Key Management Service 开发人员指南》中 creating symmetric encryption KMS keys 的步骤进行操作。

权限

您需要通过 KMS 密钥的密钥策略授予 AWS KMS 权限。

配置客户自主管理型密钥需要拥有创建或更新该函数的主体的 AWS KMS 权限。调用持久性函数不需要调用者的 AWS KMS 权限;Lambda 使用其服务主体来执行加密。

密钥策略

密钥策略控制对客户自主管理型密钥的访问。每个 KMS 密钥必须只有一个密钥策略。在密钥策略中,Resource: "*" 仅会引用附加到该策略的 KMS 密钥,而不会引用您账户中的所有 KMS 密钥。

持久性函数的密钥策略仅会向每个主体授予其所需的 AWS KMS 操作权限,并使用服务和函数 ARN 来限定作用域。以下部分介绍了策略语句、条件和一个完整示例。

必需的策略语句

该策略会授予以下权限:

  • 启用 IAM 用户权限。向账户根用户授予管理密钥的无条件访问权限。此语句不使用任何条件,因为限定作用域会妨碍您轮换、更新或删除密钥。

  • 允许 Lambda 将此密钥用于持久性函数。向 Lambda 服务主体授予 kms:GenerateDataKeykms:Decrypt 权限。

  • 允许函数执行角色解密持久性执行数据。向执行角色授予 kms:Decrypt 权限以读取状态和继续执行。

  • 允许函数创建者描述此密钥。授予 kms:DescribeKey 权限以便 Lambda 可以验证密钥是否为对称密钥并且是在 CreateFunctionUpdateFunctionConfiguration 期间启用的。

  • 允许函数创建者为特定函数验证此密钥。授予 kms:GenerateDataKeykms:Decrypt 权限,以便 Lambda 可以在 CreateFunctionUpdateFunctionConfiguration 期间使用函数的加密上下文验证密钥权限和访问权限。这将确认密钥策略在创建或更新此特定函数之前接受对该函数的调用。

  • 允许持久性执行操作者。向操作者授予 kms:Decrypt 权限,以调用 GetDurableExecution、具有 IncludeExecutionData=trueGetDurableExecutionHistoryGetDurableExecutionStateStopDurableExecution 以及回调 API。

根据最佳实践,应为执行角色、函数创建者和持久性执行操作者使用单独的主体,确保每个身份都只拥有所需的权限。

建议使用的策略条件

该策略使用以下条件来缩小作用域:

  • kms:ViaService 将密钥使用范围限定为通过 Lambda 路由的请求。将此应用于执行角色、函数创建者和操作者语句,可以防止其直接通过 AWS KMS 使用密钥。

  • aws:SourceArnaws:SourceAccount 用于防止跨服务混淆代理问题。Lambda 在使用自己的服务凭证调用 AWS KMS 时会转发这些值。此条件仅适用于 Lambda 服务主体语句。执行角色、函数作者和操作者语句会使用调用者的转发访问会话凭证调用 AWS KMS,这些凭证不具有这些标头。

  • kms:EncryptionContext:aws:lambda:FunctionArn 用于密钥的作用域限定为特定的函数。每次为持久性执行数据调用 AWS KMS 时,Lambda 都会将此语句添加到加密上下文中。

以下示例是上述语句和条件的组合。

例持久性函数的密钥策略
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow Lambda to use this key for durable functions", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": [ "kms:GenerateDataKey", "kms:Decrypt" ], "Resource": "*", "Condition": { "StringEquals": { "aws:SourceAccount": "111122223333", "aws:SourceArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction", "kms:EncryptionContext:aws:lambda:FunctionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction" } } }, { "Sid": "Allow the function execution role to decrypt durable execution data", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/myDurableFunctionRole" }, "Action": "kms:Decrypt", "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "lambda.us-east-1.amazonaws.com", "kms:EncryptionContext:aws:lambda:FunctionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction" } } }, { "Sid": "Allow the function author to describe this key", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/FunctionAuthor" }, "Action": "kms:DescribeKey", "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "lambda.us-east-1.amazonaws.com" } } }, { "Sid": "Allow the function author to validate this key for a specific function", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/FunctionAuthor" }, "Action": [ "kms:GenerateDataKey", "kms:Decrypt" ], "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "lambda.us-east-1.amazonaws.com", "kms:EncryptionContext:aws:lambda:FunctionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction" } } }, { "Sid": "Allow durable execution operators", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/DurableExecutionOperator" }, "Action": "kms:Decrypt", "Resource": "*", "Condition": { "StringEquals": { "kms:ViaService": "lambda.us-east-1.amazonaws.com", "kms:EncryptionContext:aws:lambda:FunctionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction" } } } ] }

有关 AWS KMS 密钥策略的更多信息,请参阅《AWS Key Management Service 开发人员指南》中的 How to change a key policy

在持久性函数上配置客户自主管理型密钥

您可以通过 DurableConfig 对象的 KMSKeyArn 字段为持久性执行数据配置客户自主管理型密钥。使用 CreateFunction 创建函数时对其进行设置;使用 UpdateFunctionConfiguration 在现有持久性函数上对其进行更新。

Lambda console
在现有持久性函数上配置客户自主管理型密钥
  1. 打开 Lamba 控制台的函数页面。

  2. 选择一个持久性函数。

  3. 选择配置,然后从左侧导航栏中选择持久性执行

  4. 选择编辑

  5. 加密下,选择使用客户自主管理型密钥,然后从列表中选择一个 KMS 密钥。

  6. 选择保存

AWS CLI

在创建函数时配置客户自主管理型密钥

在下面的 create-function 示例中,--durable-config 选项用于指定客户自主管理型密钥 ARN 以及持久性执行超时和保留期。

aws lambda create-function \ --function-name myDurableFunction \ --runtime nodejs24.x \ --handler index.handler \ --role arn:aws:iam::111122223333:role/myDurableFunctionRole \ --zip-file fileb://function.zip \ --durable-config '{"KMSKeyArn":"arn:aws:kms:us-east-1:111122223333:key/key-id","ExecutionTimeout":3600,"RetentionPeriodInDays":30}'

在现有持久性函数上配置客户自主管理型密钥

使用 update-function-configuration 命令。包括要保留的所有 DurableConfig 字段,因为 --durable-config 会替换整个对象。

aws lambda update-function-configuration \ --function-name myDurableFunction \ --durable-config '{"KMSKeyArn":"arn:aws:kms:us-east-1:111122223333:key/key-id","ExecutionTimeout":3600,"RetentionPeriodInDays":30}'

从持久性函数中移除客户自主管理型密钥

省略 --durable-config 中的 KMSKeyArn。现有执行会继续使用其开始时使用的客户自主管理型密钥。新执行将改为使用默认加密。

aws lambda update-function-configuration \ --function-name myDurableFunction \ --durable-config '{"ExecutionTimeout":3600,"RetentionPeriodInDays":30}'
AWS CloudFormation

AWS::Lambda::Function 资源中,设置 DurableConfigKMSKeyArn 属性。

Resources: MyDurableFunction: Type: AWS::Lambda::Function Properties: FunctionName: myDurableFunction Runtime: nodejs24.x Handler: index.handler Role: !GetAtt MyDurableFunctionRole.Arn Code: ZipFile: | // Your durable function code DurableConfig: KMSKeyArn: "arn:aws:kms:us-east-1:111122223333:key/key-id" ExecutionTimeout: 3600 RetentionPeriodInDays: 30
重要

每次持久性执行都会使用函数启动时在函数上配置的客户自主管理型密钥。更改或移除该密钥仅会影响更改后开始的执行;已经开始的执行会继续使用其开始时使用的密钥,直至完成或失败。

读取持久性执行数据

两个读取 API 会返回持久性执行数据:

  • GetDurableExecution 会返回单个执行的当前状态,包括其输入有效载荷、最新检查点数据以及结果或错误信息。

  • GetDurableExecutionHistory 会返回执行所发出事件的顺序列表,显示检查点输入和结果、链式调用输入和结果以及最终结果。

这两个 API 都接受 IncludeExecutionData 请求参数。如果 IncludeExecutionData 设置为 true,则 Lambda 会使用调用者的凭证在客户自主管理型密钥上调用 kms:Decrypt。然后,Lambda 将在响应中返回解密后的执行数据。调用者的身份必须具有客户自主管理型密钥的 kms:Decrypt 权限。

IncludeExecutionData 设置为 false 时,Lambda 不会调用 AWS KMS 或解密执行数据,并且响应会将 ExecutionDataIncluded 设置为 false。响应中仍会包含 DurableConfig,与执行时使用的客户自主管理型密钥 ARN 对应。IncludeExecutionData 将默认为 false,因此只需要元数据的调用者不需要具有 AWS KMS 权限。

示例:包含 IncludeExecutionData=falseGetDurableExecution 响应

{ "DurableExecutionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction:execution:exec-abc123", "DurableExecutionName": "exec-abc123", "FunctionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction", "StartTimestamp": 1733256000, "Status": "RUNNING", "ExecutionDataIncluded": false, "DurableConfig": { "ExecutionTimeout": 3600, "KMSKeyArn": "arn:aws:kms:us-east-1:111122223333:key/key-id", "RetentionPeriodInDays": 30 } }

链式调用

当一个持久性函数对另一个持久性函数进行链式调用时,Lambda 会将子执行视为独立的持久性执行:该子执行将有自己的执行 ID、自己的检查点流和自己的客户自主管理型密钥。父级的客户自主管理型密钥配置对子级的数据没有影响,子级的客户自主管理型密钥配置对父级的数据也没有影响。

权限

Lambda 服务主体必须具有子函数客户自主管理型密钥的 kms:GenerateDataKeykms:Decrypt 权限。如果父函数和子函数使用不同的客户自主管理型密钥,则应分别向服务主体授予对每个密钥的访问权限。父函数的执行角色不需要具有子函数客户自主管理型密钥的权限。

识别哪个密钥用于加密哪个执行

GetDurableExecutionListDurableExecutionsByFunction 都会返回加密每个执行的客户自主管理型密钥 ARN。使用这些 API 来确认父执行或子执行开始时生效的密钥。

数据密钥缓存

为减少 AWS KMS 调用量并提高服务中断期间的可用性,Lambda 会将从客户自主管理型密钥生成的数据密钥缓存不超过 15 分钟。当缓存处于热态时,Lambda 会在执行中的操作以及在缓存期内启动的执行中重复使用同一数据密钥。

成本

每个执行的 AWS KMS 成本保持较低,这是因为 Lambda 在每个缓存期内最多调用一次 GenerateDataKey,而不是在每个检查点调用一次。在高请求速率下,每个执行的成本会进一步下降,因为会有更多的执行共享每个缓存的数据密钥。您需要按照 Lambda 实际执行的 AWS KMS 调用数付费,而不是按每个检查点或读取次数付费。

静态稳定性

数据密钥将缓存不超过 15 分钟。对密钥的更改将在下一次缓存刷新时生效。在长时间服务中断期间,Lambda 会继续从缓存中提供服务,从而保持已启动执行的运行。

CloudTrail

由于数据密钥缓存的原因,您在 CloudTrail 中看到的 GenerateDataKey 事件数会少于执行或检查点数。有关示例事件,请参阅监控持久性函数的 KMS 密钥

当客户自主管理型密钥不可用时

如果执行开始时使用的客户自主管理型密钥被禁用、计划删除或已通过密钥策略撤销其访问权限,则执行将无法继续进行。在下一个检查点时,Lambda 会因不可重试的 AWS KMS 错误而使执行失败。恢复对该密钥的访问权限不会自动恢复执行。您必须启动新的执行。

当密钥不可用时,读取或写入有效载荷的 API 也会失败。结果可能会返回以下异常之一:

  • KMSAccessDeniedException:Lambda 无法解密持久性执行数据,因为对 KMS 密钥的访问被拒绝。

  • KMSDisabledException:Lambda 无法解密持久性执行数据,因为 KMS 密钥已被禁用。

  • KMSInvalidStateException:Lambda 无法解密持久性执行数据,因为 KMS 密钥的状态对于 Decrypt 无效。

  • KMSNotFoundException:Lambda 无法解密持久性执行数据,因为找不到 KMS 密钥。

如果恢复对 KMS 密钥的访问权限,可以让这些读取 API 再次成功执行已经失败的执行。失败的执行将保持失败状态;您必须重新启动执行。

要检查 KMS 密钥不可用期间的执行元数据,请使用 IncludeExecutionData=false 调用 GetDurableExecution。这将返回执行的状态、时间戳和 DurableConfig(包括 KMS 密钥 ARN),且无需调用 AWS KMS。

由于 Lambda 会缓存数据密钥,因此禁用密钥不会立即生效。有关更多信息,请参阅 数据密钥缓存

重要

如果删除已经开始或保留的执行仍然在依赖的 KMS 密钥,则会永久销毁这些执行及其历史记录。

监控持久性函数的 KMS 密钥

将客户自主管理型密钥用于持久性函数时,您可以使用 AWS CloudTrail 来跟踪 Lambda 代表您进行的 AWS KMS 调用。有关搜索 AWS KMS 事件的一般指南,请参阅 Searching AWS KMS API activity

要确认 Lambda 对密钥的使用是否符合预期,请查找每个事件中的以下字段:

  • eventNameGenerateDataKeyDecryptDescribeKey 之一

  • eventSource: kms.amazonaws.com

  • userIdentity.invokedBy: lambda.amazonaws.com

  • requestParameters.encryptionContext.aws:lambda:FunctionArn:持久性函数的 ARN

以下示例是来自 CreateFunctionUpdateFunctionConfiguration 调用的 CloudTrail 事件,该调用在持久性函数上配置了一个客户自主管理型密钥。Lambda 会发出三个 AWS KMS 调用来验证密钥:真实的 DescribeKey、试运行 GenerateDataKeyDecrypt

GenerateDataKey

当您设置或更改 DurableConfig 中的 KMSKeyArn 时,Lambda 会对您的客户自主管理型密钥发出试运行 GenerateDataKey,以验证密钥策略是否允许 Lambda 为该函数的加密上下文派生数据密钥。试运行不会执行任何加密操作,但会记录完整的 CloudTrail 事件。以下示例事件记录了试运行 GenerateDataKey 操作:

{ "eventVersion": "1.11", "userIdentity": { "type": "AssumedRole", "principalId": "AROA123456789EXAMPLE:example", "arn": "arn:aws:sts::111122223333:assumed-role/FunctionAuthor/example", "accountId": "111122223333", "accessKeyId": "ASIA123456789EXAMPLE", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA123456789EXAMPLE", "arn": "arn:aws:iam::111122223333:role/FunctionAuthor", "accountId": "111122223333", "userName": "FunctionAuthor" }, "attributes": { "creationDate": "2026-01-15T16:54:42Z", "mfaAuthenticated": "false" } }, "invokedBy": "lambda.amazonaws.com" }, "eventTime": "2026-01-15T16:55:00Z", "eventSource": "kms.amazonaws.com", "eventName": "GenerateDataKey", "awsRegion": "us-east-1", "sourceIPAddress": "lambda.amazonaws.com", "userAgent": "lambda.amazonaws.com", "errorCode": "DryRunOperationException", "errorMessage": "The request would have succeeded, but the DryRun option is set.", "requestParameters": { "encryptionContext": { "aws:lambda:FunctionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction" }, "dryRun": true, "keyId": "arn:aws:kms:us-east-1:111122223333:key/key-id", "keySpec": "AES_256" }, "responseElements": null, "additionalEventData": { "keyMaterialId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0EXAMPLE" }, "requestID": "a1b2c3d4-5678-90ab-cdef-EXAMPLEaaaaa", "eventID": "a1b2c3d4-5678-90ab-cdef-EXAMPLEbbbbb", "readOnly": true, "resources": [ { "accountId": "111122223333", "type": "AWS::KMS::Key", "ARN": "arn:aws:kms:us-east-1:111122223333:key/key-id" } ], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111122223333", "eventCategory": "Management" }
Decrypt

当您设置或更改 DurableConfig 中的 KMSKeyArn 时,Lambda 还会对您的客户自主管理型密钥发出试运行 Decrypt,以验证密钥策略是否允许 Lambda 为该函数的加密上下文解密数据。试运行使用的是 IGNORE_CIPHERTEXT,因此不需要真正的加密文字。以下示例事件记录了试运行 Decrypt 操作:

{ "eventVersion": "1.11", "userIdentity": { "type": "AssumedRole", "principalId": "AROA123456789EXAMPLE:example", "arn": "arn:aws:sts::111122223333:assumed-role/FunctionAuthor/example", "accountId": "111122223333", "accessKeyId": "ASIA123456789EXAMPLE", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA123456789EXAMPLE", "arn": "arn:aws:iam::111122223333:role/FunctionAuthor", "accountId": "111122223333", "userName": "FunctionAuthor" }, "attributes": { "creationDate": "2026-01-15T16:54:42Z", "mfaAuthenticated": "false" } }, "invokedBy": "lambda.amazonaws.com" }, "eventTime": "2026-01-15T16:55:00Z", "eventSource": "kms.amazonaws.com", "eventName": "Decrypt", "awsRegion": "us-east-1", "sourceIPAddress": "lambda.amazonaws.com", "userAgent": "lambda.amazonaws.com", "errorCode": "DryRunOperationException", "errorMessage": "The request would have succeeded, but the DryRun option is set.", "requestParameters": { "encryptionContext": { "aws:lambda:FunctionArn": "arn:aws:lambda:us-east-1:111122223333:function:myDurableFunction" }, "dryRun": true, "keyId": "arn:aws:kms:us-east-1:111122223333:key/key-id", "dryRunModifiers": ["IGNORE_CIPHERTEXT"], "encryptionAlgorithm": "SYMMETRIC_DEFAULT" }, "responseElements": null, "additionalEventData": { "keyMaterialId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0EXAMPLE" }, "requestID": "a1b2c3d4-5678-90ab-cdef-EXAMPLEaaaaa", "eventID": "a1b2c3d4-5678-90ab-cdef-EXAMPLEbbbbb", "readOnly": true, "resources": [ { "accountId": "111122223333", "type": "AWS::KMS::Key", "ARN": "arn:aws:kms:us-east-1:111122223333:key/key-id" } ], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111122223333", "eventCategory": "Management" }
DescribeKey

当您设置或更改 DurableConfig 中的 KMSKeyArn 时,Lambda 会调用 DescribeKey 来确认密钥是否为对称密钥并且是其接受更改前启用的。与 GenerateDataKeyDecrypt 探测器不同,这是一个真实的调用,而不是试运行。以下示例事件记录了 DescribeKey 操作:

{ "eventVersion": "1.11", "userIdentity": { "type": "AssumedRole", "principalId": "AROA123456789EXAMPLE:example", "arn": "arn:aws:sts::111122223333:assumed-role/FunctionAuthor/example", "accountId": "111122223333", "accessKeyId": "ASIA123456789EXAMPLE", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA123456789EXAMPLE", "arn": "arn:aws:iam::111122223333:role/FunctionAuthor", "accountId": "111122223333", "userName": "FunctionAuthor" }, "attributes": { "creationDate": "2026-01-15T16:54:42Z", "mfaAuthenticated": "false" } }, "invokedBy": "lambda.amazonaws.com" }, "eventTime": "2026-01-15T16:55:00Z", "eventSource": "kms.amazonaws.com", "eventName": "DescribeKey", "awsRegion": "us-east-1", "sourceIPAddress": "lambda.amazonaws.com", "userAgent": "lambda.amazonaws.com", "requestParameters": { "keyId": "arn:aws:kms:us-east-1:111122223333:key/key-id" }, "responseElements": null, "requestID": "a1b2c3d4-5678-90ab-cdef-EXAMPLEaaaaa", "eventID": "a1b2c3d4-5678-90ab-cdef-EXAMPLEbbbbb", "readOnly": true, "resources": [ { "accountId": "111122223333", "type": "AWS::KMS::Key", "ARN": "arn:aws:kms:us-east-1:111122223333:key/key-id" } ], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111122223333", "eventCategory": "Management" }