

# Encrypting Lambda .zip deployment packages
<a name="encrypt-zip-package"></a>

Lambda always provides server-side encryption at rest for .zip deployment packages and function configuration details with an Amazon KMS key. By default, Lambda uses an [Amazon owned key](https://docs.amazonaws.cn/kms/latest/developerguide/concepts.html#aws-owned-cmk). If this default behavior suits your workflow, you don't need to set up anything else. Amazon doesn't charge you to use this key.

If you prefer, you can provide an Amazon KMS customer managed key instead. You might do this to have control over rotation of the KMS key or to meet the requirements of your organization for managing KMS keys. When you use a customer managed key, only users in your account with access to the KMS key can view or manage the function's code or configuration.

Customer managed keys incur standard Amazon KMS charges. For more information, see [Amazon Key Management Service pricing](https://www.amazonaws.cn/kms/pricing/).

## Create a customer managed key
<a name="create-key"></a>

 You can create a symmetric customer managed key by using the Amazon Web Services Management Console, or the Amazon KMS APIs.

**To create a symmetric customer managed key**

Follow the steps for [Creating symmetric encryption Creating symmetric KMS keys](https://docs.amazonaws.cn/kms/latest/developerguide/create-keys.html#create-symmetric-cmk) in the *Amazon Key Management Service Developer Guide*.

### Permissions
<a name="enable-zip-permissions"></a>

**Key policy**

[Key policies](https://docs.amazonaws.cn/kms/latest/developerguide/key-policies.html) control access to your customer managed key. Every customer managed key must have exactly one key policy, which contains statements that determine who can use the key and how they can use it. For more information, see [How to change a key policy](https://docs.amazonaws.cn/kms/latest/developerguide/key-policy-modifying.html#key-policy-modifying-how-to) in the *Amazon Key Management Service Developer Guide*.

When you use a customer managed key to encrypt a .zip deployment package, Lambda doesn't add a [grant](https://docs.amazonaws.cn/kms/latest/developerguide/grants.html) to the key. Instead, your Amazon KMS key policy must allow Lambda to call the following Amazon KMS API operations on your behalf:
+ [kms:GenerateDataKey](https://docs.amazonaws.cn/kms/latest/APIReference/API_GenerateDataKey.html)
+ [kms:Decrypt](https://docs.amazonaws.cn/kms/latest/APIReference/API_Decrypt.html)

The following example key policy allows all Lambda functions in account 111122223333 to call the required Amazon KMS operations for the specified customer managed key:

**Example Amazon KMS key policy**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": [
                "{{kms:GenerateDataKey}}",
                "kms:Decrypt"
            ],
            "Resource": "{{arn:aws-cn:kms:us-east-1:111122223333:key/key-id}}",
            "Condition": {
                "StringLike": {
                "kms:EncryptionContext:aws:lambda:FunctionArn": "arn:aws-cn:lambda:us-east-1:{{111122223333}}:function:*"
                }
            }
        }
    ]
}
```

For more information about [troubleshooting key access](https://docs.amazonaws.cn/kms/latest/developerguide/policy-evaluation.html#example-no-iam), see the *Amazon Key Management Service Developer Guide*.

**Principal permissions**

When you use a customer managed key to encrypt a .zip deployment package, only [principals](https://docs.amazonaws.cn/IAM/latest/UserGuide/intro-structure.html) with access to that key can access the .zip deployment package. For example, principals who don't have access to the customer managed key can't download the .zip package using the presigned S3 URL that's included in the [GetFunction](https://docs.amazonaws.cn/lambda/latest/api/API_GetFunction.html) response. An `AccessDeniedException` is returned in the `Code` section of the response.

**Example Amazon KMS AccessDeniedException**  

```
{
    "Code": {
        "RepositoryType": "S3",
        "Error": {
            "ErrorCode": "AccessDeniedException",
            "Message": "KMS access is denied. Check your KMS permissions. KMS Exception: AccessDeniedException KMS Message: User: arn:aws:sts::111122223333:assumed-role/LambdaTestRole/session is not authorized to perform: kms:Decrypt on resource: arn:aws-cn:kms:us-east-1:111122223333:key/key-id with an explicit deny in a resource-based policy"
        },
        "SourceKMSKeyArn": "arn:aws-cn:kms:us-east-1:111122223333:key/key-id"
    },
	...
```

For more information about permissions for Amazon KMS keys, see [Authentication and access control for Amazon KMS](https://docs.amazonaws.cn/kms/latest/developerguide/control-access.html).

## Using a customer managed key for your .zip deployment package
<a name="enable-zip-custom-encryption"></a>

Use the following API parameters to configure customer managed keys for .zip deployment packages:
+ [SourceKMSKeyArn](https://docs.amazonaws.cn/lambda/latest/api/API_FunctionCode.html#lambda-Type-FunctionCode-SourceKMSKeyArn): Encrypts the source .zip deployment package (the file that you upload).
+ [KMSKeyArn](https://docs.amazonaws.cn/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-KMSKeyArn): Encrypts [environment variables](configuration-envvars-encryption.md) and [Lambda SnapStart](snapstart.md) snapshots.

When `SourceKMSKeyArn` and `KMSKeyArn` are both specified, Lambda uses the `KMSKeyArn` key to encrypt the unzipped version of the package that Lambda uses to invoke the function. When `SourceKMSKeyArn` is specified but `KMSKeyArn` is not, Lambda uses an [Amazon managed key](https://docs.amazonaws.cn/kms/latest/developerguide/concepts.html#aws-managed-cmk) to encrypt the unzipped version of the package.

------
#### [ Lambda console ]

**To add customer managed key encryption when you create a function**

1. Open the [Functions page](https://console.amazonaws.cn/lambda/home#/functions) of the Lambda console.

1. Choose **Create function**.

1. Choose **Author from scratch** or **Container image**. 

1. Under **Basic information**, do the following:

   1. For **Function name**, enter the function name.

   1. For **Runtime**, choose the language version to use for your function.

1. Expand **Advanced settings**, and then select **Enable encryption with an Amazon KMS customer managed key**.

1. Choose a customer managed key.

1. Choose **Create function**.

To remove customer managed key encryption, or to use a different key, you must upload the .zip deployment package again.

**To add customer managed key encryption to an existing function**

1. Open the [Functions page](https://console.amazonaws.cn/lambda/home#/functions) of the Lambda console.

1. Choose the name of a function.

1. In the **Code source** pane, choose **Upload from**.

1. Choose **.zip file** or **Amazon S3 location**.  
![Upload .zip file from code source pane](http://docs.amazonaws.cn/en_us/lambda/latest/dg/images/upload-zip.png)

1. Upload the file or enter the Amazon S3 location.

1. Choose **Enable encryption with an Amazon KMS customer managed key**.

1. Choose a customer managed key.

1. Choose **Save**.

------
#### [ Amazon CLI ]

**To add customer managed key encryption when you create a function**

In the following [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) example:
+ `--code`: Specifies the local path to the .zip deployment package (`ZipFile`) and the customer managed key to encrypt it (`SourceKMSKeyArn`).
+ `--kms-key-arn`: Specifies the customer managed key to encrypt the environment variables and the unzipped version of the deployment package.

```
aws lambda create-function \
  --function-name myFunction \
  --runtime nodejs24.x \
  --handler index.handler \
  --role arn:aws-cn:iam::111122223333:role/service-role/my-lambda-role \
  --code ZipFile=fileb://{{myFunction.zip}},SourceKMSKeyArn={{arn:aws-cn:kms:us-east-1:111122223333:key/key-id}} \
  --kms-key-arn {{arn:aws-cn:kms:us-east-1:111122223333:key/key2-id}}
```

In the following [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) example:
+ `--code`: Specifies the location of the .zip file in an Amazon S3 bucket (`S3Bucket`, `S3Key`, `S3ObjectVersion`) and the customer managed key to encrypt it (`SourceKMSKeyArn`).
+ `--kms-key-arn`: Specifies the customer managed key to encrypt the environment variables and the unzipped version of the deployment package.

```
aws lambda create-function \
  --function-name myFunction \
  --runtime nodejs24.x --handler index.handler \
  --role arn:aws-cn:iam::111122223333:role/service-role/my-lambda-role \
  --code S3Bucket={{amzn-s3-demo-bucket}},S3Key={{myFileName.zip}},S3ObjectVersion={{myObjectVersion}},SourceKMSKeyArn={{arn:aws-cn:kms:us-east-1:111122223333:key/key-id}} \
  --kms-key-arn {{arn:aws-cn:kms:us-east-1:111122223333:key/key2-id}}
```

**To add customer managed key encryption to an existing function**

In the following [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) example:
+ `--zip-file`: Specifies the local path to the .zip deployment package.
+ `--source-kms-key-arn`: Specifies the customer managed key to encrypt the zipped version of the deployment package. Lambda uses an Amazon owned key to encrypt the unzipped package for function invocations. If you want to use a customer managed key to encrypt the unzipped version of the package, run the [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) command with the `--kms-key-arn` option.

```
aws lambda update-function-code \
  --function-name myFunction \
  --zip-file fileb://{{myFunction.zip}} \
  --source-kms-key-arn {{arn:aws-cn:kms:us-east-1:111122223333:key/key-id}}
```

In the following [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) example:
+ `--s3-bucket`: Specifies the location of the .zip file in an Amazon S3 bucket.
+ `--s3-key`: Specifies the Amazon S3 key of the deployment package.
+ `--s3-object-version`: For versioned objects, the version of the deployment package object to use.
+ `--source-kms-key-arn`: Specifies the customer managed key to encrypt the zipped version of the deployment package. Lambda uses an Amazon owned key to encrypt the unzipped package for function invocations. If you want to use a customer managed key to encrypt the unzipped version of the package, run the [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) command with the `--kms-key-arn` option.

```
aws lambda update-function-code \
  --function-name myFunction \
  --s3-bucket {{amzn-s3-demo-bucket}} \
  --s3-key {{myFileName.zip}} \
  --s3-object-version {{myObject Version}}
  --source-kms-key-arn {{arn:aws-cn:kms:us-east-1:111122223333:key/key-id}}
```

**To remove customer managed key encryption from an existing function**

In the following [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) example, `--zip-file` specifies the local path to the .zip deployment package. When you run this command without the `--source-kms-key-arn` option, Lambda uses an Amazon owned key to encrypt the zipped version of the deployment package.

```
aws lambda update-function-code \
  --function-name myFunction \
  --zip-file fileb://{{myFunction.zip}}
```

------