Skip to content

Commit

Permalink
feature: Support for Lambda Code Signing (#53) (#1825) (#1828)
Browse files Browse the repository at this point in the history
* feature: add support for CFN fields for lambda signing (#53)

* feature: add support for CFN fields for lambda signing

* feature: add support for CFN fields for lambda signing (update formatting)

* feature: add support for CFN fields for lambda signing (update patching)

* feature: add support for CFN fields for lambda signing (update template)

* Revert "feat: add explicit UpdateReplacePolicy (#1481)" (#1568)

* docs: document IpV6 option on Domain Configuration object (#1588)

* chore: Exclude test modules in whl (#1597)

* feat: Add Step Function Resource (#1601)

Co-authored-by: Jacob Fuss <jfuss@users.noreply.github.com>

* Release Changes for 1.25.0

* feature: add support for CFN fields for lambda signing

* feature: add support for CFN fields for lambda signing (slight code update)

* feature: add support for CFN fields for lambda signing (update globals.py)

Co-authored-by: Shreya <shreyagangishetty@gmail.com>
Co-authored-by: Timo Schilling <timo@schilling.io>
Co-authored-by: Jacob Fuss <32497805+jfuss@users.noreply.github.com>
Co-authored-by: Jacob Fuss <jfuss@users.noreply.github.com>
Co-authored-by: Alex Wood <awood45@gmail.com>

* Move Tests to Appveyor (#1801)

* print python version

* update path vars

* update linux cmd

* update linux cmd

* update linux cmd

* update whitelist in tox

* update passenv

* update tox whitelisting

* update tox whitelisting

Co-authored-by: Shreya <shreyagangishetty@gmail.com>
Co-authored-by: Timo Schilling <timo@schilling.io>
Co-authored-by: Jacob Fuss <32497805+jfuss@users.noreply.github.com>
Co-authored-by: Jacob Fuss <jfuss@users.noreply.github.com>
Co-authored-by: Alex Wood <awood45@gmail.com>

Co-authored-by: Shreya <shreyagangishetty@gmail.com>
Co-authored-by: Timo Schilling <timo@schilling.io>
Co-authored-by: Jacob Fuss <32497805+jfuss@users.noreply.github.com>
Co-authored-by: Jacob Fuss <jfuss@users.noreply.github.com>
Co-authored-by: Alex Wood <awood45@gmail.com>
  • Loading branch information
6 people authored Nov 23, 2020
1 parent f6d9c8c commit 1948145
Show file tree
Hide file tree
Showing 10 changed files with 318 additions and 2 deletions.
1 change: 1 addition & 0 deletions samtranslator/model/lambda_.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class LambdaFunction(Resource):
"Layers": PropertyType(False, list_of(one_of(is_str(), is_type(dict)))),
"ReservedConcurrentExecutions": PropertyType(False, any_type()),
"FileSystemConfigs": PropertyType(False, list_of(is_type(dict))),
"CodeSigningConfigArn": PropertyType(False, is_str()),
}

runtime_attrs = {"name": lambda self: ref(self.logical_id), "arn": lambda self: fnGetAtt(self.logical_id, "Arn")}
Expand Down
3 changes: 3 additions & 0 deletions samtranslator/model/sam_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class SamFunction(SamResourceMacro):
"VersionDescription": PropertyType(False, is_str()),
"ProvisionedConcurrencyConfig": PropertyType(False, is_type(dict)),
"FileSystemConfigs": PropertyType(False, list_of(is_type(dict))),
"CodeSigningConfigArn": PropertyType(False, is_str()),
}
event_resolver = ResourceTypeResolver(
samtranslator.model.eventsources,
Expand Down Expand Up @@ -412,6 +413,8 @@ def _construct_lambda_function(self):
if self.DeadLetterQueue:
lambda_function.DeadLetterConfig = {"TargetArn": self.DeadLetterQueue["TargetArn"]}

lambda_function.CodeSigningConfigArn = self.CodeSigningConfigArn

return lambda_function

def _add_event_invoke_managed_policy(self, dest_config, logical_id, condition, dest_arn):
Expand Down
1 change: 1 addition & 0 deletions samtranslator/plugins/globals/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Globals(object):
"AssumeRolePolicyDocument",
"EventInvokeConfig",
"FileSystemConfigs",
"CodeSigningConfigArn",
],
# Everything except
# DefinitionBody: because its hard to reason about merge of Swagger dictionaries
Expand Down
24 changes: 24 additions & 0 deletions tests/translator/input/function_with_signing_profile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Resources:

FunctionWithSigningProfile:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://sam-demo-bucket/member_portal.zip
Handler: index.gethtml
Runtime: nodejs12.x
CodeSigningConfigArn: !Ref MySignedFunctionCodeSigningConfig

MySignedFunctionCodeSigningConfig:
Type: AWS::Lambda::CodeSigningConfig
Properties:
Description: "Code Signing for MySignedLambdaFunction"
AllowedPublishers:
SigningProfileVersionArns:
- !GetAtt SigningProfile.ProfileVersionArn
CodeSigningPolicies:
UntrustedArtifactOnDeployment: "Enforce"

SigningProfile:
Type: AWS::Signer::SigningProfile
Properties:
PlatformId: AWSLambda-SHA384-ECDSA
85 changes: 85 additions & 0 deletions tests/translator/output/aws-cn/function_with_signing_profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"Resources": {
"FunctionWithSigningProfile": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.gethtml",
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "member_portal.zip"
},
"Runtime": "nodejs12.x",
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
],
"Role": {
"Fn::GetAtt": [
"FunctionWithSigningProfileRole",
"Arn"
]
},
"CodeSigningConfigArn": {
"Ref": "MySignedFunctionCodeSigningConfig"
}
}
},
"FunctionWithSigningProfileRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
]
},
"ManagedPolicyArns": [
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
]
}
},
"MySignedFunctionCodeSigningConfig": {
"Type": "AWS::Lambda::CodeSigningConfig",
"Properties": {
"CodeSigningPolicies": {
"UntrustedArtifactOnDeployment": "Enforce"
},
"AllowedPublishers": {
"SigningProfileVersionArns": [
{
"Fn::GetAtt": [
"SigningProfile",
"ProfileVersionArn"
]
}
]
},
"Description": "Code Signing for MySignedLambdaFunction"
}
},
"SigningProfile": {
"Type": "AWS::Signer::SigningProfile",
"Properties": {
"PlatformId": "AWSLambda-SHA384-ECDSA"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"Resources": {
"FunctionWithSigningProfile": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.gethtml",
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "member_portal.zip"
},
"Runtime": "nodejs12.x",
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
],
"Role": {
"Fn::GetAtt": [
"FunctionWithSigningProfileRole",
"Arn"
]
},
"CodeSigningConfigArn": {
"Ref": "MySignedFunctionCodeSigningConfig"
}
}
},
"FunctionWithSigningProfileRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
]
},
"ManagedPolicyArns": [
"arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
]
}
},
"MySignedFunctionCodeSigningConfig": {
"Type": "AWS::Lambda::CodeSigningConfig",
"Properties": {
"CodeSigningPolicies": {
"UntrustedArtifactOnDeployment": "Enforce"
},
"AllowedPublishers": {
"SigningProfileVersionArns": [
{
"Fn::GetAtt": [
"SigningProfile",
"ProfileVersionArn"
]
}
]
},
"Description": "Code Signing for MySignedLambdaFunction"
}
},
"SigningProfile": {
"Type": "AWS::Signer::SigningProfile",
"Properties": {
"PlatformId": "AWSLambda-SHA384-ECDSA"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"errors": [
{
"errorMessage": "'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions', 'ProvisionedConcurrencyConfig', 'EventInvokeConfig', 'FileSystemConfigs']"
"errorMessage": "'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions', 'ProvisionedConcurrencyConfig', 'EventInvokeConfig', 'FileSystemConfigs', 'CodeSigningConfigArn']"
}
],
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. 'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions', 'ProvisionedConcurrencyConfig', 'AssumeRolePolicyDocument', 'EventInvokeConfig', 'FileSystemConfigs']"
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. 'Globals' section is invalid. 'SomeKey' is not a supported property of 'Function'. Must be one of the following values - ['Handler', 'Runtime', 'CodeUri', 'DeadLetterQueue', 'Description', 'MemorySize', 'Timeout', 'VpcConfig', 'Environment', 'Tags', 'Tracing', 'KmsKeyArn', 'AutoPublishAlias', 'Layers', 'DeploymentPreference', 'PermissionsBoundary', 'ReservedConcurrentExecutions', 'ProvisionedConcurrencyConfig', 'AssumeRolePolicyDocument', 'EventInvokeConfig', 'FileSystemConfigs', 'CodeSigningConfigArn']"
}
85 changes: 85 additions & 0 deletions tests/translator/output/function_with_signing_profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"Resources": {
"FunctionWithSigningProfile": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.gethtml",
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "member_portal.zip"
},
"Runtime": "nodejs12.x",
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
],
"Role": {
"Fn::GetAtt": [
"FunctionWithSigningProfileRole",
"Arn"
]
},
"CodeSigningConfigArn": {
"Ref": "MySignedFunctionCodeSigningConfig"
}
}
},
"FunctionWithSigningProfileRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
]
}
},
"MySignedFunctionCodeSigningConfig": {
"Type": "AWS::Lambda::CodeSigningConfig",
"Properties": {
"CodeSigningPolicies": {
"UntrustedArtifactOnDeployment": "Enforce"
},
"AllowedPublishers": {
"SigningProfileVersionArns": [
{
"Fn::GetAtt": [
"SigningProfile",
"ProfileVersionArn"
]
}
]
},
"Description": "Code Signing for MySignedLambdaFunction"
}
},
"SigningProfile": {
"Type": "AWS::Signer::SigningProfile",
"Properties": {
"PlatformId": "AWSLambda-SHA384-ECDSA"
}
}
}
}
31 changes: 31 additions & 0 deletions tests/translator/test_function_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,37 @@ def setUp(self):
self.lambda_func = self._make_lambda_function(self.sam_func.logical_id)
self.lambda_version = self._make_lambda_version("VersionLogicalId", self.sam_func)

@patch("boto3.session.Session.region_name", "us-west-2")
def test_sam_function_with_code_signer(self):
code_signing_config_arn = "code_signing_config_arn"
func = {
"Type": "AWS::Serverless::Function",
"Properties": {
"CodeUri": self.code_uri,
"Runtime": "nodejs12.x",
"Handler": "index.handler",
"CodeSigningConfigArn": code_signing_config_arn,
},
}

sam_func = SamFunction.from_dict(logical_id="foo", resource_dict=func)

kwargs = {}
kwargs["managed_policy_map"] = {"a": "b"}
kwargs["event_resources"] = []
kwargs["intrinsics_resolver"] = self.intrinsics_resolver_mock
self.intrinsics_resolver_mock.resolve_parameter_refs.return_value = {
"S3Bucket": "bucket",
"S3Key": "key",
"S3ObjectVersion": "version",
}
resources = sam_func.to_cloudformation(**kwargs)

lambda_functions = [r.to_dict() for r in resources if r.resource_type == LambdaFunction.resource_type]
self.assertEqual(len(lambda_functions), 1)
expected_code_signing_config_arn = lambda_functions[0]["foo"]["Properties"]["CodeSigningConfigArn"]
self.assertEqual(expected_code_signing_config_arn, code_signing_config_arn)

@patch("boto3.session.Session.region_name", "ap-southeast-1")
@patch.object(SamFunction, "_get_resolved_alias_name")
def test_sam_function_with_alias(self, get_resolved_alias_name_mock):
Expand Down
1 change: 1 addition & 0 deletions tests/translator/test_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ class TestTranslatorEndToEnd(TestCase):
"function_with_conditional_policy_template",
"function_with_conditional_policy_template_and_ref_no_value",
"function_with_request_parameters",
"function_with_signing_profile",
"global_handle_path_level_parameter",
"globals_for_function",
"globals_for_api",
Expand Down

0 comments on commit 1948145

Please sign in to comment.