aws / aws-cdk-rfcs

RFCs for the AWS CDK

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

support code signing of assets

dontirun opened this issue · comments

Related to aws/aws-cdk#12656 , aws/aws-cdk#12216

Created a Lambda SignedCode.fromAsset option that takes local code uploads it to S3 and signs it using a specified AWS signer profile

Use Case

With PR aws/aws-cdk#12656 Lambda now supports a code signing configuration. However if the signing config is set to Enforce and local code (inline or from asset path) is provided the deployment will fail as the code has not been signed

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

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

      new lambda.Function(stack, 'MyLambda', {
        code: new lambda.Code.fromAsset(...),
        handler: 'index.handler',
        runtime: lambda.Runtime.NODEJS_10_X,
        codeSigningConfig,
      });

this feature would enable usage of local code and signing of the the code given permissions to the signing profile

Proposed Solution

Having an option like

     new lambda.Function(stack, 'MyLambda', {
        code: new lambda.SignedCode.fromAsset(...),
        handler: 'index.handler',
        runtime: lambda.Runtime.NODEJS_10_X,
        codeSigningConfig,
      });

would solve this issue

Other

  1. This is how the SAM CLI does it
  2. The bootstrap bucket would need to have versioning enabled
  • 👋 I may be able to implement this feature request
  • ⚠️ This feature might incur a breaking change

This is a 🚀 Feature Request

I read the code around aws-lmabda.code, and I thought the following part is a good way to extend it.

https://github.com/aws/aws-cdk/blob/1fcdb6daf931147b8f33facb8ab9c9f80e5c9eee/packages/%40aws-cdk/core/lib/asset-staging.ts#L161-L169

In the case of aws-lambda-nodejs, the following values can be passed to the constructor of aws-lambda.Function to build the code with esbuild.

code: Code.fromAsset(path.dirname(options.depsLockFilePath), {
  assetHashType: cdk.AssetHashType.OUTPUT,
  Bundling: new Bundling(options),
})

Building process is executed locally by default, but if esbuild command not available in the environment, executed in compatible docker container.

As for signatures, is it possible to rely on the local environment?
Also, which tool should I rely on, AWS CLI, AWS SDK, etc.?

(Once we have a policy for implementation, I would like to start implementing it.)

Looks like something for cdk-assets?

I read the code around aws-lmabda.code, and I thought the following part is a good way to extend it.

https://github.com/aws/aws-cdk/blob/1fcdb6daf931147b8f33facb8ab9c9f80e5c9eee/packages/%40aws-cdk/core/lib/asset-staging.ts#L161-L169

In the case of aws-lambda-nodejs, the following values can be passed to the constructor of aws-lambda.Function to build the code with esbuild.

code: Code.fromAsset(path.dirname(options.depsLockFilePath), {
  assetHashType: cdk.AssetHashType.OUTPUT,
  Bundling: new Bundling(options),
})

Building process is executed locally by default, but if esbuild command not available in the environment, executed in compatible docker container.

As for signatures, is it possible to rely on the local environment?
Also, which tool should I rely on, AWS CLI, AWS SDK, etc.?

(Once we have a policy for implementation, I would like to start implementing it.)

I don't think we need to touch the local bundling. The signing need to occur after the object has been uploaded to the S3 bucket (I believe the upload is done here. ) I believe an optimal approach is to follow what the SAM CLI does with their python code

  1. Add an optional parameter with the profile name(without the version)
  2. Start the signing job
  3. Use the built in waiter for the signing job to complete.

In addition, the CDK bootstrap bucket would need to be changed to have versioning enabled ( since Signer requires a versioned object in S3 to start a signing job)

Thank you. I misunderstood it as something to be signed locally.

I understand that we should start signing job after s3.upload.
https://github.com/aws/aws-cdk/blob/05a998065b3333854715c456b20b7cc5d5daac67/packages/cdk-assets/lib/private/handlers/files.ts#L51-L56

To specify asset that need to be singed, should we path profile name of signer here?,,

https://github.com/aws/aws-cdk/blob/05a998065b3333854715c456b20b7cc5d5daac67/packages/%40aws-cdk/aws-s3-assets/lib/asset.ts#L147-L151

If we set up the signing profile name when synth and start signing job in the middle of publishAsset when deploying, we may need to change cloud-assembly.scheme, but in that case, we'll need to upgrade a major version of schema.

Is there any good way to do this?

We currently don't have the ability in the CDK to run an asynchronous job (i.e., the signing job) and use the result as an asset.

This requires additional design into the AWS CDK lifecycle. I'm moving this to the CDK RFC repo to manage the design work.

Unfortunately, we don't have the bandwidth to work on this in the near future.
However, if anyone is interested in writing the design, we'll be happy to review and provide feedback.

Just curious if there have been any thoughts on this since the original posts. We're actively using CDK now and would like to have our code signed for compliance purposes. Are there any clever approaches we can leverage here, or do we need to build our own process from scratch?

Closing as we unfortunately do not have the bandwidth to work on this in the near future. We suggest to pursue experimentation in a separate package or a fork if needed. If a successful implementation emerges, reopen the proposal with details on the functionality and how it can be implemented in the core library.