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.71k stars 3.94k forks source link

aws_lambda: enforced code signing causes deployment failure #29474

Open cjhelloletsgo opened 8 months ago

cjhelloletsgo commented 8 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 8 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 8 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 8 months ago

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

cjhelloletsgo commented 2 months ago

This is still a problem, I have a repo here to help reproduce the problem. https://github.com/cjhelloletsgo/cdk_signing_profile_issue

pahud commented 2 months ago

Yes now I can reproduce this

export class DummyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    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,
    });

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

6:41:26 PM | CREATE_FAILED | AWS::Lambda::Function | MyFunction Resource handler returned message: "Lambda cannot deploy the function. The function or layer might be signed u sing a signature that the client is not configured to accept. Check the provided signature for dummy-stackk-My Function3BAA72D1-wrnBDfNVr1Ik." (RequestToken: d6b8497f-0573-c147-72f4-f5264e22883f, HandlerErrorCode: Invalid Request)

CDK v2.158.0

synth

{
 "Resources": {
  "SigningProfile2E013C934": {
   "Type": "AWS::Signer::SigningProfile",
   "Properties": {
    "PlatformId": "AWSLambda-SHA384-ECDSA",
    "SignatureValidityPeriod": {
     "Type": "MONTHS",
     "Value": 135
    }
   },
   "Metadata": {
    "aws:cdk:path": "dummy-stackk/SigningProfile2/Resource"
   }
  },
  "CodeSigningConfig202ACE0C5": {
   "Type": "AWS::Lambda::CodeSigningConfig",
   "Properties": {
    "AllowedPublishers": {
     "SigningProfileVersionArns": [
      {
       "Fn::GetAtt": [
        "SigningProfile2E013C934",
        "ProfileVersionArn"
       ]
      }
     ]
    },
    "CodeSigningPolicies": {
     "UntrustedArtifactOnDeployment": "Enforce"
    }
   },
   "Metadata": {
    "aws:cdk:path": "dummy-stackk/CodeSigningConfig2/Resource"
   }
  },
  "MyFunctionServiceRole3C357FF2": {
   "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-stackk/MyFunction/ServiceRole/Resource"
   }
  },
  "MyFunction3BAA72D1": {
   "Type": "AWS::Lambda::Function",
   "Properties": {
    "Code": {
     "S3Bucket": "cdk-hnb659fds-assets-903779448426-us-east-1",
     "S3Key": "3988ba077676d6ed0bb4481ec971bf54da0c66e1ff656338ecfe5b3a001c5511.zip"
    },
    "CodeSigningConfigArn": {
     "Fn::GetAtt": [
      "CodeSigningConfig202ACE0C5",
      "CodeSigningConfigArn"
     ]
    },
    "Handler": "index.handler",
    "Role": {
     "Fn::GetAtt": [
      "MyFunctionServiceRole3C357FF2",
      "Arn"
     ]
    },
    "Runtime": "nodejs18.x"
   },
   "DependsOn": [
    "MyFunctionServiceRole3C357FF2"
   ],
   "Metadata": {
    "aws:cdk:path": "dummy-stackk/MyFunction/Resource",
    "aws:asset:path": "asset.3988ba077676d6ed0bb4481ec971bf54da0c66e1ff656338ecfe5b3a001c5511",
    "aws:asset:is-bundled": false,
    "aws:asset:property": "Code"
   }
  },
  "CDKMetadata": {
   "Type": "AWS::CDK::Metadata",
   "Properties": {
    "Analytics": "v2:deflate64:H4sIAAAAAAAA/2WNwWrDQAxEvyV3WXUSQnttDD0X+wOCspYXxbYWrHVyWPbfg+P4UHp6w7yBOeD+9IXljh5WuLYvBrliaiK5Huhhl2TilSdMjXgV9b9T6GRgqDr922QYaLy2hKkKLb9dFbQTv4z/lz+zuihBF7vlDEIjpjqsDwsz2PFCZhwNvxeAHfE8u57jmYwz1GxhnhzDyzaRvOjrchMZNLSMN/u4H0rcf2K5u5lIMc0aZWSsVz4BnGZHOQkBAAA="
   },
   "Metadata": {
    "aws:cdk:path": "dummy-stackk/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."
    }
   ]
  }
 }
}
pahud commented 2 months ago

I am making it a p1 bug now.

cjhelloletsgo commented 2 months ago

Thank you!

pahud commented 2 months ago

@cjhelloletsgo FYI we are still investigating. Will let you know shortly if we have any updates.

pahud commented 2 months ago

Looks like it's Lambda service's responsibility to proceed the signing operation but I can't find relevant document about it.

image

I'll cut an internal ticket for clarifying.

pahud commented 2 months ago

internal tracking: V1521555433

pahud commented 2 months ago

I believe it's relevant to https://github.com/aws/aws-cdk/issues/12216#issuecomment-784290273 which mentioned that CDK actually didn't sign the bundle from local and https://github.com/aws/aws-cdk-rfcs/issues/305 was attempting to address that but was closed. At this moment, I am afraid you need to sign the bundle using AWS CLI start-signing-job or from the AWS Signer console.

We still welcome any idea to continue from where https://github.com/aws/aws-cdk-rfcs/issues/305#issuecomment-1858352721 was stopped. I will submit a small PR to mention that in the lambda doc.

cjhelloletsgo commented 2 months ago

From reading through those links it seems this is broken with no plans of being fixed? Are you saying I can use start-signing-job somehow in the bundling options? Doing it through the signer console doesn't make sense as I am deploying through the CLI how would that be possible?

github-actions[bot] commented 2 months ago

Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.

github-actions[bot] commented 2 months ago

Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.

pahud commented 2 months ago

From reading through those links it seems this is broken with no plans of being fixed? Are you saying I can use start-signing-job somehow in the bundling options? Doing it through the signer console doesn't make sense as I am deploying through the CLI how would that be possible?

Yes unfortunately CDK CLI at this moment does not support it out-of-the-box and the experience would not be expected.

My workaround here. This is not great but it explains how it works in action.

  1. cdk synth to synthesize assets into cdk.out.
  2. publish the assets using npx cdk-assets -p cdk.out/your_stack_name.assets.json publish
  3. you need to have a script like this to sign the zip bundle into a new file and rename it back to the origin filename

Using Shell Script

#!/bin/sh
set -x

ZIP_FILE='a5936dcaa6ccdbc6eacb1209c70d2eed716e9040937124c26b5cc53b954846a0.zip'
PROFILE_NAME='SigningProfile2139A0F9_IvT8c6lPa2rl'
BUCKET='cdk-hnb659fds-assets-123456789012-us-east-1'

LATEST_VERSION=$(aws s3api list-object-versions \
  --bucket $BUCKET \
  --prefix $ZIP_FILE \
  --query 'Versions[0].VersionId' \
  --output text)

JOB_ID=$(aws signer start-signing-job \
  --source "s3={bucketName=$BUCKET,key=$ZIP_FILE, version=$LATEST_VERSION}" \
  --destination "s3={bucketName=$BUCKET,prefix=signed-}" \
  --profile-name $PROFILE_NAME --query 'jobId' --output text)

sleep 2
# get the signedObject s3 key
newObjectKey=$(aws signer describe-signing-job --job-id $JOB_ID --query signedObject.s3.key --output text)

# rename the signed object to origin object name
aws s3 mv s3://$BUCKET/$newObjectKey s3://$BUCKET/$ZIP_FILE
  1. finally, cdk deploy, it should work!

Using Python

If you are comfortable with python, this is my proof of concept(by Amazon Q Developer), you can revise and build your own tool like this before CDK CLI has native support for that.

import json, boto3, time

# Path to your JSON file
file_path = '/Your/Path/To/cdk.out/dummy-stack.assets.json'
profile_name = 'SigningProfile2139A0F9_IvT8c6lPa2rl'

# Function to parse the JSON and extract required information
def parse_assets_json(file_path):
    with open(file_path, 'r') as file:
        data = json.load(file)

    assets = []
    for asset_id, asset_info in data.get('files', {}).items():
        source = asset_info.get('source', {})
        destinations = asset_info.get('destinations', {})

        # Get the first destination (assuming there's only one)
        destination = next(iter(destinations.values()), {})

        packaging = source.get('packaging')
        object_key = destination.get('objectKey')
        bucket_name = destination.get('bucketName')

        if packaging == 'zip' and object_key and bucket_name:
            assets.append({
                'assetId': asset_id,
                'packaging': packaging,
                'objectKey': object_key,
                'bucketName': bucket_name
            })

    return assets

# get_latest_version()
def get_latest_version(s3, bucket_name, object_key):
    response = s3.list_object_versions(
        Bucket=bucket_name,
        Prefix=object_key,
        MaxKeys=1
    )
    if 'Versions' in response and response['Versions']:
        return response['Versions'][0]['VersionId']
    return None

def sign_s3_object(bucket_name, object_key, profile_name, destination_bucket=None):
    # Initialize AWS clients
    session = boto3.Session()
    s3 = session.client('s3')
    signer = session.client('signer')
    my_account = session.client('sts').get_caller_identity()['Account']

    # If destination bucket is not specified, use the source bucket
    if not destination_bucket:
        destination_bucket = bucket_name

    # Start the signing job
    response = signer.start_signing_job(
        source={
            's3': {
                'bucketName': bucket_name,
                'key': object_key,
                'version': get_latest_version(s3, bucket_name, object_key)
            }
        },
        destination={
            's3': {
                'bucketName': destination_bucket,
                'prefix': 'sign-',
            }
        },
        profileName=profile_name
    )

    job_id = response['jobId']
    print(f"Signing job started. Job ID: {job_id}")
    # sleep 5 seconds
    time.sleep(5)
    # get signed_object_key from a new describing signing job call
    response = signer.describe_signing_job(jobId=job_id)
    print(response)
    signed_object_key = response['signedObject'].get('s3').get('key')

    # Wait for the signing job to complete
    while True:
        response = signer.describe_signing_job(jobId=job_id)
        status = response['status']
        if status == 'Succeeded':
            break
        elif status in ['Failed', 'Revoked']:
            raise Exception(f"Signing job failed with status: {status}")
        time.sleep(5)  # Wait for 5 seconds before checking again

    # Get the signed object key
    print(f"Signing completed. Signed object key: {signed_object_key}")

    # Move the signed object to replace the original object
    s3.copy_object(
        Bucket=bucket_name,
        CopySource={'Bucket': destination_bucket, 'Key': signed_object_key},
        Key=object_key,
        ExpectedBucketOwner=my_account,
        ExpectedSourceBucketOwner=my_account,

    )
    print(f"Signed object moved to original key: {object_key}")

    # Delete the temporary signed object
    s3.delete_object(Bucket=destination_bucket, Key=signed_object_key)
    print(f"Temporary signed object deleted: {signed_object_key}")

    return object_key

# Parse the JSON file
result = parse_assets_json(file_path)

# Print the results
for asset in result:
    print(f"Asset ID: {asset['assetId']}")
    print(f"Object Key: {asset['objectKey']}")
    print(f"Bucket Name: {asset['bucketName']}")
    print("---")
    # sign the object
    sign_s3_object(asset['bucketName'], asset['objectKey'], profile_name=profile_name)

Output:

Signing completed. Signed object key: sign-5e21daf1-d34e-4233-bbe2-e63207d7c914.zip Signed object moved to original key: a5936dcaa6ccdbc6eacb1209c70d2eed716e9040937124c26b5cc53b954846a0.zip Temporary signed object deleted: sign-5e21daf1-d34e-4233-bbe2-e63207d7c914.zip

Now, I just reopened this issue as p2 feature request.

We welcome community PRs and please help us prioritize with 👍 on the issue description.