- Knowledge Base
- Amazon Web Services
- AWS Lambda
- Enable Code Signing
Ensure that all your Amazon Lambda functions are configured to use the Code Signing feature in order to restrict the deployment of unverified code. With Code Signing, you can ensure that the function code has been signed by an approved (trusted) source, has not been altered since signing, and that the code signature has not expired or been revoked.
This rule can help you work with the AWS Well-Architected Framework.
Code Signing for Lambda provides a first-class mechanism to ensure that only verified code from trusted publishers is deployed within Amazon Lambda. With Code Signing for Lambda, you can configure your Amazon Lambda functions to only accept signed code on deployment. When your developers deploy signed code to such functions, Amazon Lambda checks the signatures to ensure that the code is not altered. In addition, the cloud service ensures that the code is signed by trusted developers before accepting the deployment. The Code Signing feature uses AWS Signer, a fully managed code signing service from AWS cloud. AWS Signer provides a mechanism to ensure that only signed and trusted Amazon Lambda functions are deployed by an organization. The Signer service defines a trusted publisher in a signing profile. Authorized developers use this profile to generate certified code packages, and Amazon Lambda verifies signatures and package integrity when the code is deployed.
Audit
To determine if your Amazon Lambda functions are configured to use Code Signing, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon Lambda console at https://console.aws.amazon.com/lambda/.
03 In the left navigation panel, under AWS Lambda, choose Functions.
04 Click on the name (link) of the function that you want to examine.
05 Select the Configuration tab and choose Code signing from the left menu.
06 In the Code signing configuration section, check for any code signing configurations created for the selected function. A code signing configuration defines a list of allowed signing profiles and defines the code-signing validation policy (i.e. action to be taken if the function deployment validation checks fail). If there are no code signing configurations available in the Code signing configuration section, the Code Signing feature is not enabled for the selected Amazon Lambda function.
07 Repeat steps no. 4 – 6 for each Lambda function available within the current AWS region.
08 Change the AWS cloud region from the console navigation bar and repeat the Audit process for other regions.
Using AWS CLI
01 Run list-functions command (OSX/Linux/UNIX) to list the name of each Amazon Lambda function available in the selected AWS cloud region:
aws lambda list-functions --region us-east-1 --output table --query 'Functions[*].FunctionName'
02 The command output should return a table with the requested function name(s):
--------------------- | ListFunctions | +-------------------+ | cc-sqs-poller | | cc-s3-logging | | s3-get-object | +-------------------+
03 Run get-function-code-signing-config command (OSX/Linux/UNIX) using the name of the Amazon Lambda function that you want to examine as the identifier parameter and custom query filters to describe the Amazon Resource Name (ARN) of each code signing configuration created for the selected function:
aws lambda get-function-code-signing-config --region us-east-1 --function-name cc-sqs-poller --query 'CodeSigningConfigArn'
04 The command output should return an array with the requested ARN(s):
null
If the get-function-code-signing-config command output returns null, as shown in the example above, there are no code signing configurations created for the selected resource, therefore the Code Signing feature is not enabled for the selected Amazon Lambda function.
05 Repeat step no. 3 and 4 for each Lambda function available in the selected AWS region.
06 Change the AWS region by updating the --region command parameter value and repeat steps no. 1 – 5 to perform the Audit process for other regions.
Remediation / Resolution
To enable and configure the Code Signing feature for your Amazon Lambda functions, perform the following operations:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "LambdaFunctionExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": "LambdaExecutionRole", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/", "Policies": [ { "PolicyName": "AWSLambdaBasicExecutionRole", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "ec2:DescribeNetworkInterfaces", "ec2:CreateNetworkInterface", "ec2:DeleteNetworkInterface", "ec2:DescribeInstances", "ec2:AttachNetworkInterface" ], "Resource": "*" } ] } } ] } }, "AWSSignerProfile": { "Type": "AWS::Signer::SigningProfile", "Properties": { "PlatformId": "AWSLambda-SHA384-ECDSA", "SignatureValidityPeriod": { "Type": "YEARS", "Value": 5 } } }, "LambdaCodeSigningConfig": { "Type": "AWS::Lambda::CodeSigningConfig", "Properties": { "AllowedPublishers": { "SigningProfileVersionArns": [ { "Fn::GetAtt": [ "AWSSignerProfile", "Arn" ] } ] }, "CodeSigningPolicies": { "UntrustedArtifactOnDeployment": "Enforce" } } }, "LambdaFunction": { "Type": "AWS::Lambda::Function", "Properties": { "FunctionName": "cc-app-worker-function", "Handler": "lambda_function.lambda_handler", "Role": { "Fn::GetAtt": [ "LambdaFunctionExecutionRole", "Arn" ] }, "Code": { "S3Bucket": "cc-lambda-functions", "S3Key": "worker.zip" }, "Runtime": "python3.9", "MemorySize": 1024, "Timeout": 45, "VpcConfig": { "SecurityGroupIds": [ "sg-0abcd1234abcd1234" ], "SubnetIds": [ "subnet-abcd1234", "subnet-1234abcd" ] }, "CodeSigningConfigArn": { "Ref": "LambdaCodeSigningConfig" } } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Resources: LambdaFunctionExecutionRole: Type: AWS::IAM::Role Properties: RoleName: LambdaExecutionRole AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: AWSLambdaBasicExecutionRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - ec2:DescribeNetworkInterfaces - ec2:CreateNetworkInterface - ec2:DeleteNetworkInterface - ec2:DescribeInstances - ec2:AttachNetworkInterface Resource: '*' AWSSignerProfile: Type: AWS::Signer::SigningProfile Properties: PlatformId: AWSLambda-SHA384-ECDSA SignatureValidityPeriod: Type: YEARS Value: 5 LambdaCodeSigningConfig: Type: AWS::Lambda::CodeSigningConfig Properties: AllowedPublishers: SigningProfileVersionArns: - !GetAtt 'AWSSignerProfile.Arn' CodeSigningPolicies: UntrustedArtifactOnDeployment: Enforce LambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: cc-app-worker-function Handler: lambda_function.lambda_handler Role: !GetAtt 'LambdaFunctionExecutionRole.Arn' Code: S3Bucket: cc-lambda-functions S3Key: worker.zip Runtime: python3.9 MemorySize: 1024 Timeout: 45 VpcConfig: SecurityGroupIds: - sg-0abcd1234abcd1234 SubnetIds: - subnet-abcd1234 - subnet-1234abcd CodeSigningConfigArn: !Ref 'LambdaCodeSigningConfig'
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_iam_role" "lambda-execution-role" { name = "LambdaExecutionRole" path = "/" managed_policy_arns = [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"] assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "lambda.amazonaws.com" }, "Effect": "Allow" } ] } EOF } resource "aws_signer_signing_profile" "aws-signing-profile" { name_prefix = "cc-lambda-signing-profile" platform_id = "AWSLambda-SHA384-ECDSA" signature_validity_period { type = "YEARS" value = 5 } } resource "aws_lambda_code_signing_config" "lambda-code-signing-config" { allowed_publishers { signing_profile_version_arns = [aws_signer_signing_profile.aws-signing-profile.version_arn] } policies { untrusted_artifact_on_deployment = "Enforce" } } resource "aws_lambda_function" "lambda-function" { function_name = "cc-app-worker-function" role = aws_iam_role.lambda-execution-role.arn handler = "lambda_function.lambda_handler" runtime = "python3.9" memory_size = 1024 timeout = 45 vpc_config { subnet_ids = [ "subnet-01234abcd1234abcd", "subnet-0abcd1234abcd1234" ] security_group_ids = [ "sg-0abcd1234abcd1234" ] } code_signing_config_arn = aws_lambda_code_signing_config.lambda-code-signing-config.arn }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Create a Signing Profile using AWS Signer. A Signing Profile is a trusted publisher and is analogous to the use of a digital signing certificate to generate signatures for your application code. To get started, navigate to AWS Signer console at https://console.aws.amazon.com/signer.
03 In the left navigation panel, under AWS Signer, select Signing Profiles.
04 Choose Create Signing Profile to create a Signing Profile that can be used to create signed code packages.
05 On the Create Signing Profile setup page, provide a unique name for your new Signing Profile and specify the Signature Validity period (between 1 day and 135 months) for the signatures generated by the Signing Profile. Choose Create Profile to create the required Signing Profile.
06 Navigate to Amazon Lambda console at https://console.aws.amazon.com/lambda/.
07 In the left navigation panel, under Additional resources, choose Code signing configurations.
08 Choose Create configuration to create a code signing configuration that defines signing profiles that are allowed to sign code artifacts for the new configuration, and set a signature validation policy.
09 On the Create code signing configuration setup page, perform the following actions:
- In the Description box, provide a short description to identify this configuration when you add it to a Lambda function.
- Click inside the Signing profile version ARN box and select the Amazon Resource Name (ARN) of the Signing Profile created at step no. 5.
- For Signature validation policy, choose the signature validation policy suitable for your Lambda function. A signature check can fail if the code is not signed by an allowed Signing Profile, or if the signature has expired or has been revoked. When a signature check fails, Amazon Lambda can treat the deployment in two ways:
- Warn – Amazon Lambda allows the deployment of the code bundle but issues a warning. The service also stores a warning containing the details about the signature check in the CloudTrail log.
- Enforce – Lambda blocks the deployment of the code and also issues a warning. However, regardless of your validation policy, if your code has been tampered or altered since signing, the deployment will be blocked.
- Choose Create configuration to deploy your new code signing configuration.
10 In the left navigation panel, under AWS Lambda, choose Functions.
11 Click on the name of the function that you want to reconfigure.
12 Select the Configuration tab and choose Code signing from the left menu.
13 Click on the Edit button available in the Code signing configuration section to add a code signing configuration.
14 On the Edit code signing page, select the code signing configuration created at step no. 9 from the Code signing configuration dropdown list. Choose Save to apply the changes and enable the Code Signing feature.
15 Once your Amazon Lambda function is configured to use code signing, you need to upload a signed .zip file or provide an S3 URL of a signed .zip made by a signing job in AWS Signer. To start a signing job, navigate back to AWS Signer console at https://console.aws.amazon.com/signer.
16 In the left navigation panel, under AWS Signer, select Signing Jobs.
17 Choose Start Signing Job to deploy a new Signing Job. A Signing Job represents an asynchronous process that generates a signature for your code package and puts the signed code package in the specified destination path.
18 On the Start Signing Job setup page, perform the following actions:
- Select the Signing Profile created at step no. 5 from the Signing Profile to use dropdown list.
- For Code asset source location, specify the Amazon S3 location of the code package (.zip file) to be signed. Only S3 buckets available in the current region are displayed. Cross-region signing is not yet supported.
- For Signature destination path with prefix, specify a destination path where the signed code package should be uploaded.
- Choose Start Job to deploy your new Signing Job. Once the job status becomes Succeeded, you can find the signed .zip package in your assigned S3 bucket.
19 You can now publish the signed code package to the selected Lambda function. Amazon Lambda will perform signature checks to verify that the code has not been altered since signing. Also, the service verifies if the code is signed by one of the allowed signing profiles available.
20 Repeat steps no. 2 – 19 to enable and configure Code Signing feature for each Amazon Lambda function available within the current AWS region.
21 Change the AWS cloud region from the navigation bar and repeat the Remediation process for the other regions.
Using AWS CLI
01 Run put-signing-profile command (OSX/Linux/UNIX) to create a new AWS Signer Signing Profile. A Signing Profile defines a trusted publisher who can sign a code package:
aws signer put-signing-profile --region us-east-1 --profile-name cc_lambda_signing_profile --platform-id AWSLambda-SHA384-ECDSA --signature-validity-period value=135,type="MONTHS"
02 The command output should return the ARN (including the version ARN) of the newly created Signing Profile:
{ "arn": "arn:aws:signer:us-east-1:123456789012:/signing-profiles/cc_lambda_signing_profile", "profileVersion": "abcdabcdac", "profileVersionArn": "arn:aws:signer:us-east-1:123456789012:/signing-profiles/cc_lambda_signing_profile/abcdabcdac" }
03 Run create-code-signing-config command (OSX/Linux/UNIX) to create a code signing configuration for the Amazon Lambda function that you want to enable Code Signing. A code signing configuration defines signing profiles that are allowed to sign code artifacts for the new configuration and set a signature validation policy. Use the Signing Profile created at the previous step as allowed (trusted) publisher. The following command example makes use of the "Enforce" code signing configuration policy for deployment validation failure. With this policy type, Amazon Lambda blocks the deployment of the code when a signature check fails:
aws lambda create-code-signing-config --region us-east-1 --description cc-sqs-poller-code-signing-config --allowed-publishers SigningProfileVersionArns=arn:aws:signer:us-east-1:123456789012:/signing-profiles/cc_lambda_signing_profile/abcdabcdac --code-signing-policies UntrustedArtifactOnDeployment="Enforce"
04 The command output should return the metadata available for the new Lambda code signing configuration:
{ "CodeSigningConfig": { "CodeSigningConfigId": "csc-0abcd1234abcd1234", "CodeSigningConfigArn": "arn:aws:lambda:us-east-1:123456789012:code-signing-config:csc-0abcd1234abcd1234", "Description": "cc-sqs-poller-code-signing-config", "AllowedPublishers": { "SigningProfileVersionArns": [ "arn:aws:signer:us-east-1:123456789012:/signing-profiles/cc_lambda_signing_profile/abcdabcdac" ] }, "CodeSigningPolicies": { "UntrustedArtifactOnDeployment": "Enforce" }, "LastModified": "2021-01-13T10:10:10.000000Z" } }
05 Run put-function-code-signing-config command (OSX/Linux/UNIX) to apply the newly created code signing configuration to the specified Lambda function. This will enable Code Signing feature for your Amazon Lambda function:
aws lambda put-function-code-signing-config --region us-east-1 --code-signing-config-arn arn:aws:lambda:us-east-1:123456789012:code-signing-config:csc-0abcd1234abcd1234 --function-name cc-sqs-poller
06 The output should return the put-function-code-signing-config command request metadata:
{ "CodeSigningConfigArn": "arn:aws:lambda:us-east-1:123456789012:code-signing-config:csc-0abcd1234abcd1234", "FunctionName": "cc-sqs-poller" }
07 Once your Amazon Lambda function is configured to use code signing, you need to upload a signed .zip file or provide an S3 URL of a signed .zip made by a signing job in AWS Signer. To initiate a Signing Job to be performed on the code provided, run start-signing-job command (OSX/Linux/UNIX). A Signing Job represents an asynchronous process that generates a signature for your code package and puts the signed code package in the specified destination path. Choose the Signing Profile created at step no. 1 and specify the Amazon S3 location of the code package (.zip file) to be signed. Also, include the destination path where the signed code package should be uploaded:
aws signer start-signing-job --region us-east-1 --source 's3={bucketName=cc-signer-source,key=code.zip,version=ABCDABCDABCDABCDABCDABCDABCDABCD}' --destination 's3={bucketName=cc-signer-destination,prefix=signed-}' --profile-name cc_lambda_signing_profile
08 The command output should return the identifier (ID) of the new AWS Signer Signing Job:
{ "jobId": "abcd1234-abcd-1234-abcd-1234abcd1234", "jobOwner": "123456789012" }
09 You can now publish the signed code package to the selected Lambda function. Amazon Lambda will perform signature checks to verify that the code has not been altered since signing. Also, the Lambda service verifies if the code is signed by one of the allowed signing profiles available.
10 Repeat steps no. 1 – 9 to enable and configure Code Signing feature for each Amazon Lambda function available in the selected AWS region.
11 Change the AWS cloud region by updating the --region command parameter value and repeat steps no. 1 – 10 to perform the Remediation process for other regions.
References
- AWS Documentation
- Configuring AWS Lambda functions
- Configuring code signing for AWS Lambda
- Interoperation with other AWS services
- AWS Command Line Interface (CLI) Documentation
- lambda
- list-functions
- get-function-code-signing-config
- create-code-signing-config
- put-function-code-signing-config
- signer
- put-signing-profile
- start-signing-job
Related Lambda rules
- Enable Encryption at Rest for Environment Variables using Customer Master Keys (Security)
- Lambda Functions Should not Share Roles that Contain Admin Privileges (Security)
- Enable IAM Authentication for Lambda Function URLs (Security)
- Use AWS-Managed Policies for Lambda Function Execution Roles (Security, operational-excellence)
Unlock the Remediation Steps
Free 30-day Trial
Automatically audit your configurations with Conformity
and gain access to our cloud security platform.
You are auditing:
Enable Code Signing
Risk Level: Medium