aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.47k stars 3.83k forks source link

aws_lambda: enforced code signing causes deployment failure #29474

Open cjhelloletsgo opened 5 months ago

cjhelloletsgo commented 5 months ago

Describe the bug

While configuring code signing on an aws lambda if you specify a code signing config where the untrusted_artifact_on_deployment parameter is set to ENFORCE the deployment will always fail. If the policy is set to warn there is no problem.


test_signing_profile = signer.SigningProfile(
    self,
    "Test Signing Profile",
    platform=signer.Platform.AWS_LAMBDA_SHA384_ECDSA,
)

test_code_signing_config = lambda_.CodeSigningConfig(
    self,
    "Test Code Signing Config",
    signing_profiles=[
        test_signing_profile,
    ],
    description="Test",
    # setting untrusted_artifact_on_deployment to ENFORCE causes deployment to fail
    untrusted_artifact_on_deployment=lambda_.UntrustedArtifactOnDeployment.ENFORCE,
)

test_lambda = lambda_.Function(
    self,
    "Test Lambda",
    runtime=lambda_.Runtime.PYTHON_3_12,
    handler="lambda_function.lambda_handler",
    code_signing_config=test_code_signing_config,
    code=lambda_.Code.from_asset(
        "lambda/api/websocket/test",
    ),
    timeout=Duration.seconds(15),
    memory_size=256,
    architecture=lambda_.Architecture.X86_64,
    retry_attempts=0,
    description="Test Lambda delete later.",
    initial_policy=[],
)

### Expected Behavior

The lambda to be signed using the code signing configuration

### Current Behavior

The code fails to deploy with an error message: Lambda cannot deploy the function. The function or layer might be signed using a signature that the client is not configured to accept. Check the provided signature for LAMBDA_ARN_HERE

### Reproduction Steps

Create a stack with the above resources, try to deploy a lambda with warn, it will work. Try to deploy the lambda with enforce, it will not work

### Possible Solution

_No response_

### Additional Information/Context

_No response_

### CDK CLI Version

2.132.1

### Framework Version

_No response_

### Node.js Version

v20.11.1

### OS

Ubuntu 23.10

### Language

Python

### Language Version

Python 3.11

### Other information

_No response_
pahud commented 5 months ago

Hi

I was able to deploy it with UntrustedArtifactOnDeployment.ENFORCE with cdk v2.133.0.

Please check my code in TypeScript:

    const signingProfile = new signer.SigningProfile(this, 'SigningProfile', {
      platform: signer.Platform.AWS_LAMBDA_SHA384_ECDSA,
    });

    const codeSigningConfig = new lambda.CodeSigningConfig(this, 'CodeSigningConfig', {
      signingProfiles: [signingProfile],
      untrustedArtifactOnDeployment: lambda.UntrustedArtifactOnDeployment.ENFORCE,
    });

    new lambda.Function(this, 'Function', {
      codeSigningConfig,
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset(path.join(__dirname, '../lambda')),
    });

synth

Resources:
  SigningProfile2139A0F9:
    Type: AWS::Signer::SigningProfile
    Properties:
      PlatformId: AWSLambda-SHA384-ECDSA
      SignatureValidityPeriod:
        Type: MONTHS
        Value: 135
    Metadata:
      aws:cdk:path: dummy-stack4/SigningProfile/Resource
  CodeSigningConfigD8D41C10:
    Type: AWS::Lambda::CodeSigningConfig
    Properties:
      AllowedPublishers:
        SigningProfileVersionArns:
          - Fn::GetAtt:
              - SigningProfile2139A0F9
              - ProfileVersionArn
      CodeSigningPolicies:
        UntrustedArtifactOnDeployment: Enforce
    Metadata:
      aws:cdk:path: dummy-stack4/CodeSigningConfig/Resource
  FunctionServiceRole675BB04A:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    Metadata:
      aws:cdk:path: dummy-stack4/Function/ServiceRole/Resource
  Function76856677:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: cdk-hnb659fds-assets-903779448426-us-east-1
        S3Key: 297e4961275717170c4e122c4dd6e629b83080796b88b6716027321ec3f4e2c7.zip
      CodeSigningConfigArn:
        Fn::GetAtt:
          - CodeSigningConfigD8D41C10
          - CodeSigningConfigArn
      Handler: index.handler
      Role:
        Fn::GetAtt:
          - FunctionServiceRole675BB04A
          - Arn
      Runtime: nodejs18.x
    DependsOn:
      - FunctionServiceRole675BB04A
    Metadata:
      aws:cdk:path: dummy-stack4/Function/Resource
      aws:asset:path: asset.297e4961275717170c4e122c4dd6e629b83080796b88b6716027321ec3f4e2c7
      aws:asset:is-bundled: false
      aws:asset:property: Code
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/2WPzw6CMAzGn8X7qCKJ8Sokng0+ABljkPJnS+jQw7J3twM8GE9f+/3afO0Z0iyD00G+KVHNkIxYg386qQbBVuUJO6NntljRdI/ZtjhqUbTm1wlilFPdSPCFbfTOCmta7OLwv3lfjHJoTaTfOgiUE/jSbglRg6CskkTaEdyicA/5ogbtckmMS012mZUWK+XLO85Yt3cQhOFw6On4Sq+QXvjZnhCTeTEOJw3lph8kXNDoCQEAAA==
    Metadata:
      aws:cdk:path: dummy-stack4/CDKMetadata/Default
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.

cdk deploy works great to me. And I can see this from the lambda console.

image

Is your error coming from cloudformation? Can you share your cdk synth template? I believe it should work.

cjhelloletsgo commented 5 months ago

Sure, this is the template it generates:

Resources:
  TestSigningProfile98254211:
    Type: AWS::Signer::SigningProfile
    Properties:
      PlatformId: AWSLambda-SHA384-ECDSA
      SignatureValidityPeriod:
        Type: MONTHS
        Value: 135
    Metadata:
      aws:cdk:path: IssueStack/Test Signing Profile/Resource
  TestCodeSigningConfig2952C7DC:
    Type: AWS::Lambda::CodeSigningConfig
    Properties:
      AllowedPublishers:
        SigningProfileVersionArns:
          - Fn::GetAtt:
              - TestSigningProfile98254211
              - ProfileVersionArn
      CodeSigningPolicies:
        UntrustedArtifactOnDeployment: Enforce
      Description: Test
    Metadata:
      aws:cdk:path: IssueStack/Test Code Signing Config/Resource
  TestLambdaServiceRoleECB4CB18:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    Metadata:
      aws:cdk:path: IssueStack/Test Lambda/ServiceRole/Resource
  TestLambda93B0066B:
    Type: AWS::Lambda::Function
    Properties:
      Architectures:
        - x86_64
      Code:
        S3Bucket: cdk-hnb659fds-assets-308665918648-us-east-1
        S3Key: 851da26868933e8ab521e3bc2c318bd2a7f9220284d9b35ce3ab5c31fce99feb.zip
      CodeSigningConfigArn:
        Fn::GetAtt:
          - TestCodeSigningConfig2952C7DC
          - CodeSigningConfigArn
      Description: Test Lambda delete later.
      Handler: lambda_function.lambda_handler
      MemorySize: 256
      Role:
        Fn::GetAtt:
          - TestLambdaServiceRoleECB4CB18
          - Arn
      Runtime: python3.12
    DependsOn:
      - TestLambdaServiceRoleECB4CB18
    Metadata:
      aws:cdk:path: IssueStack/Test Lambda/Resource
      aws:asset:path: asset.851da26868933e8ab521e3bc2c318bd2a7f9220284d9b35ce3ab5c31fce99feb
      aws:asset:is-bundled: false
      aws:asset:property: Code
  TestLambdaEventInvokeConfig9F084114:
    Type: AWS::Lambda::EventInvokeConfig
    Properties:
      FunctionName:
        Ref: TestLambda93B0066B
      MaximumRetryAttempts: 0
      Qualifier: $LATEST
    Metadata:
      aws:cdk:path: IssueStack/Test Lambda/EventInvokeConfig/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/2WO0W7CMAxFv4X31IzmC6Bi0t5Q+wHIpG7w2jpSnYJQlH9HBbZp4ulY99jWLWFjLXys8KqFa/ti4BOkJqLrDV71mJS90ASpYS8s/jCFjgcyVSf/k2wGHE8tQqpCSy9XBenYL8vv4ecsLnKQxf7O+wtJ/JJL6Onv9i3MhnGEVIdnkYXZqD2iKkWF7QKjFnaz6ynuUCmbmjTMkyPzsE1Ez/L4/iOyOdziOcjawqaEcvWtzMU0S+SRoH7yDppk/rctAQAA
    Metadata:
      aws:cdk:path: IssueStack/CDKMetadata/Default
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.

As well as the entire stack if that helps

from aws_cdk import (
    Stack,
)
from aws_cdk import aws_lambda as lambda_
from aws_cdk import aws_signer as signer
from constructs import Construct

class IssueStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        test_signing_profile = signer.SigningProfile(
            self,
            "Test Signing Profile",
            platform=signer.Platform.AWS_LAMBDA_SHA384_ECDSA,
        )

        test_code_signing_config = lambda_.CodeSigningConfig(
            self,
            "Test Code Signing Config",
            signing_profiles=[
                test_signing_profile,
            ],
            description="Test",
            # setting untrusted_artifact_on_deployment to ENFORCE causes deployment to fail
            untrusted_artifact_on_deployment=lambda_.UntrustedArtifactOnDeployment.ENFORCE,
        )

        test_lambda = lambda_.Function(
            self,
            "Test Lambda",
            runtime=lambda_.Runtime.PYTHON_3_12,
            handler="lambda_function.lambda_handler",
            code_signing_config=test_code_signing_config,
            code=lambda_.Code.from_asset(
                "lambda/test",
            ),
            memory_size=256,
            architecture=lambda_.Architecture.X86_64,
            retry_attempts=0,
            description="Test Lambda delete later.",
            initial_policy=[],
        )

And a screenshot to match yours image

So everything seems good except the lambda will always fail to deploy.

cjhelloletsgo commented 5 months ago

@pahud Have you got a chance to look into this any more?