-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aws_lambda: enforced code signing causes deployment failure #29474
Comments
@pahud Have you got a chance to look into this any more? |
This is still a problem, I have a repo here to help reproduce the problem. https://github.com/cjhelloletsgo/cdk_signing_profile_issue |
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,
});
}
}
CDK v2.158.0 synth
|
I am making it a p1 bug now. |
Thank you! |
@cjhelloletsgo FYI we are still investigating. Will let you know shortly if we have any updates. |
internal tracking: V1521555433 |
I believe it's relevant to #12216 (comment) which mentioned that CDK actually didn't sign the bundle from local and aws/aws-cdk-rfcs#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 aws/aws-cdk-rfcs#305 (comment) was stopped. I will submit a small PR to mention that in the lambda doc. |
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? |
Comments on closed issues and PRs are hard for our team to see. |
1 similar comment
Comments on closed issues and PRs are hard for our team to see. |
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.
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
Using PythonIf 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:
Now, I just reopened this issue as p2 feature request. We welcome community PRs and please help us prioritize with 👍 on the issue description. |
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.
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
The text was updated successfully, but these errors were encountered: