Configure AWS Lambda Code Signing

The aws:lambda/codeSigningConfig:CodeSigningConfig resource, part of the Pulumi AWS provider, defines code signing validation rules for Lambda functions: which signing profiles are trusted and how to handle unsigned code. This guide focuses on two capabilities: enforcement policies (block vs warn) and signing profile allowlists.

Code signing configs reference AWS Signer signing profiles that must exist separately. They’re attached to Lambda functions via the function’s codeSigningConfigArn property. The examples are intentionally small. Combine them with your own signing profiles and Lambda function configurations.

Enforce code signing with multiple signing profiles

Production deployments often require strict code integrity checks to prevent unauthorized or tampered code from executing.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Create signing profiles for different environments
const prod = new aws.signer.SigningProfile("prod", {
    platformId: "AWSLambda-SHA384-ECDSA",
    namePrefix: "prod_lambda_",
    tags: {
        Environment: "production",
    },
});
const dev = new aws.signer.SigningProfile("dev", {
    platformId: "AWSLambda-SHA384-ECDSA",
    namePrefix: "dev_lambda_",
    tags: {
        Environment: "development",
    },
});
// Code signing configuration with enforcement
const example = new aws.lambda.CodeSigningConfig("example", {
    description: "Code signing configuration for Lambda functions",
    allowedPublishers: {
        signingProfileVersionArns: [
            prod.versionArn,
            dev.versionArn,
        ],
    },
    policies: {
        untrustedArtifactOnDeployment: "Enforce",
    },
    tags: {
        Environment: "production",
        Purpose: "code-signing",
    },
});
import pulumi
import pulumi_aws as aws

# Create signing profiles for different environments
prod = aws.signer.SigningProfile("prod",
    platform_id="AWSLambda-SHA384-ECDSA",
    name_prefix="prod_lambda_",
    tags={
        "Environment": "production",
    })
dev = aws.signer.SigningProfile("dev",
    platform_id="AWSLambda-SHA384-ECDSA",
    name_prefix="dev_lambda_",
    tags={
        "Environment": "development",
    })
# Code signing configuration with enforcement
example = aws.lambda_.CodeSigningConfig("example",
    description="Code signing configuration for Lambda functions",
    allowed_publishers={
        "signing_profile_version_arns": [
            prod.version_arn,
            dev.version_arn,
        ],
    },
    policies={
        "untrusted_artifact_on_deployment": "Enforce",
    },
    tags={
        "Environment": "production",
        "Purpose": "code-signing",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/signer"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		// Create signing profiles for different environments
		prod, err := signer.NewSigningProfile(ctx, "prod", &signer.SigningProfileArgs{
			PlatformId: pulumi.String("AWSLambda-SHA384-ECDSA"),
			NamePrefix: pulumi.String("prod_lambda_"),
			Tags: pulumi.StringMap{
				"Environment": pulumi.String("production"),
			},
		})
		if err != nil {
			return err
		}
		dev, err := signer.NewSigningProfile(ctx, "dev", &signer.SigningProfileArgs{
			PlatformId: pulumi.String("AWSLambda-SHA384-ECDSA"),
			NamePrefix: pulumi.String("dev_lambda_"),
			Tags: pulumi.StringMap{
				"Environment": pulumi.String("development"),
			},
		})
		if err != nil {
			return err
		}
		// Code signing configuration with enforcement
		_, err = lambda.NewCodeSigningConfig(ctx, "example", &lambda.CodeSigningConfigArgs{
			Description: pulumi.String("Code signing configuration for Lambda functions"),
			AllowedPublishers: &lambda.CodeSigningConfigAllowedPublishersArgs{
				SigningProfileVersionArns: pulumi.StringArray{
					prod.VersionArn,
					dev.VersionArn,
				},
			},
			Policies: &lambda.CodeSigningConfigPoliciesArgs{
				UntrustedArtifactOnDeployment: pulumi.String("Enforce"),
			},
			Tags: pulumi.StringMap{
				"Environment": pulumi.String("production"),
				"Purpose":     pulumi.String("code-signing"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    // Create signing profiles for different environments
    var prod = new Aws.Signer.SigningProfile("prod", new()
    {
        PlatformId = "AWSLambda-SHA384-ECDSA",
        NamePrefix = "prod_lambda_",
        Tags = 
        {
            { "Environment", "production" },
        },
    });

    var dev = new Aws.Signer.SigningProfile("dev", new()
    {
        PlatformId = "AWSLambda-SHA384-ECDSA",
        NamePrefix = "dev_lambda_",
        Tags = 
        {
            { "Environment", "development" },
        },
    });

    // Code signing configuration with enforcement
    var example = new Aws.Lambda.CodeSigningConfig("example", new()
    {
        Description = "Code signing configuration for Lambda functions",
        AllowedPublishers = new Aws.Lambda.Inputs.CodeSigningConfigAllowedPublishersArgs
        {
            SigningProfileVersionArns = new[]
            {
                prod.VersionArn,
                dev.VersionArn,
            },
        },
        Policies = new Aws.Lambda.Inputs.CodeSigningConfigPoliciesArgs
        {
            UntrustedArtifactOnDeployment = "Enforce",
        },
        Tags = 
        {
            { "Environment", "production" },
            { "Purpose", "code-signing" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.signer.SigningProfile;
import com.pulumi.aws.signer.SigningProfileArgs;
import com.pulumi.aws.lambda.CodeSigningConfig;
import com.pulumi.aws.lambda.CodeSigningConfigArgs;
import com.pulumi.aws.lambda.inputs.CodeSigningConfigAllowedPublishersArgs;
import com.pulumi.aws.lambda.inputs.CodeSigningConfigPoliciesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        // Create signing profiles for different environments
        var prod = new SigningProfile("prod", SigningProfileArgs.builder()
            .platformId("AWSLambda-SHA384-ECDSA")
            .namePrefix("prod_lambda_")
            .tags(Map.of("Environment", "production"))
            .build());

        var dev = new SigningProfile("dev", SigningProfileArgs.builder()
            .platformId("AWSLambda-SHA384-ECDSA")
            .namePrefix("dev_lambda_")
            .tags(Map.of("Environment", "development"))
            .build());

        // Code signing configuration with enforcement
        var example = new CodeSigningConfig("example", CodeSigningConfigArgs.builder()
            .description("Code signing configuration for Lambda functions")
            .allowedPublishers(CodeSigningConfigAllowedPublishersArgs.builder()
                .signingProfileVersionArns(                
                    prod.versionArn(),
                    dev.versionArn())
                .build())
            .policies(CodeSigningConfigPoliciesArgs.builder()
                .untrustedArtifactOnDeployment("Enforce")
                .build())
            .tags(Map.ofEntries(
                Map.entry("Environment", "production"),
                Map.entry("Purpose", "code-signing")
            ))
            .build());

    }
}
resources:
  # Create signing profiles for different environments
  prod:
    type: aws:signer:SigningProfile
    properties:
      platformId: AWSLambda-SHA384-ECDSA
      namePrefix: prod_lambda_
      tags:
        Environment: production
  dev:
    type: aws:signer:SigningProfile
    properties:
      platformId: AWSLambda-SHA384-ECDSA
      namePrefix: dev_lambda_
      tags:
        Environment: development
  # Code signing configuration with enforcement
  example:
    type: aws:lambda:CodeSigningConfig
    properties:
      description: Code signing configuration for Lambda functions
      allowedPublishers:
        signingProfileVersionArns:
          - ${prod.versionArn}
          - ${dev.versionArn}
      policies:
        untrustedArtifactOnDeployment: Enforce
      tags:
        Environment: production
        Purpose: code-signing

When a Lambda function references this code signing config, AWS validates the deployment package against the allowed signing profiles. The allowedPublishers block lists trusted signing profile version ARNs. The policies block controls what happens when validation fails: “Enforce” blocks deployment of unsigned or incorrectly signed code, while “Warn” allows deployment but logs a warning.

Allow unsigned code with warnings in development

Development environments need flexibility to deploy unsigned code for rapid iteration while maintaining visibility into signing status.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.lambda.CodeSigningConfig("example", {
    description: "Development code signing configuration",
    allowedPublishers: {
        signingProfileVersionArns: [dev.versionArn],
    },
    policies: {
        untrustedArtifactOnDeployment: "Warn",
    },
    tags: {
        Environment: "development",
        Purpose: "code-signing",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.lambda_.CodeSigningConfig("example",
    description="Development code signing configuration",
    allowed_publishers={
        "signing_profile_version_arns": [dev["versionArn"]],
    },
    policies={
        "untrusted_artifact_on_deployment": "Warn",
    },
    tags={
        "Environment": "development",
        "Purpose": "code-signing",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := lambda.NewCodeSigningConfig(ctx, "example", &lambda.CodeSigningConfigArgs{
			Description: pulumi.String("Development code signing configuration"),
			AllowedPublishers: &lambda.CodeSigningConfigAllowedPublishersArgs{
				SigningProfileVersionArns: pulumi.StringArray{
					dev.VersionArn,
				},
			},
			Policies: &lambda.CodeSigningConfigPoliciesArgs{
				UntrustedArtifactOnDeployment: pulumi.String("Warn"),
			},
			Tags: pulumi.StringMap{
				"Environment": pulumi.String("development"),
				"Purpose":     pulumi.String("code-signing"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Lambda.CodeSigningConfig("example", new()
    {
        Description = "Development code signing configuration",
        AllowedPublishers = new Aws.Lambda.Inputs.CodeSigningConfigAllowedPublishersArgs
        {
            SigningProfileVersionArns = new[]
            {
                dev.VersionArn,
            },
        },
        Policies = new Aws.Lambda.Inputs.CodeSigningConfigPoliciesArgs
        {
            UntrustedArtifactOnDeployment = "Warn",
        },
        Tags = 
        {
            { "Environment", "development" },
            { "Purpose", "code-signing" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lambda.CodeSigningConfig;
import com.pulumi.aws.lambda.CodeSigningConfigArgs;
import com.pulumi.aws.lambda.inputs.CodeSigningConfigAllowedPublishersArgs;
import com.pulumi.aws.lambda.inputs.CodeSigningConfigPoliciesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new CodeSigningConfig("example", CodeSigningConfigArgs.builder()
            .description("Development code signing configuration")
            .allowedPublishers(CodeSigningConfigAllowedPublishersArgs.builder()
                .signingProfileVersionArns(dev.versionArn())
                .build())
            .policies(CodeSigningConfigPoliciesArgs.builder()
                .untrustedArtifactOnDeployment("Warn")
                .build())
            .tags(Map.ofEntries(
                Map.entry("Environment", "development"),
                Map.entry("Purpose", "code-signing")
            ))
            .build());

    }
}
resources:
  example:
    type: aws:lambda:CodeSigningConfig
    properties:
      description: Development code signing configuration
      allowedPublishers:
        signingProfileVersionArns:
          - ${dev.versionArn}
      policies:
        untrustedArtifactOnDeployment: Warn
      tags:
        Environment: development
        Purpose: code-signing

Setting untrustedArtifactOnDeployment to “Warn” allows unsigned code to deploy but generates CloudWatch warnings. This relaxes enforcement from strict blocking, enabling faster development cycles while preserving audit trails.

Beyond these examples

These snippets focus on specific code signing config features: enforcement policies and signing profile allowlists. They’re intentionally minimal rather than full Lambda deployment workflows.

The examples reference pre-existing infrastructure such as AWS Signer signing profiles with version ARNs. They focus on defining validation rules rather than creating signing profiles or attaching configs to functions.

To keep things focused, common code signing patterns are omitted, including:

  • Attaching code signing configs to Lambda functions
  • Signing profile creation and management
  • Multi-region code signing configurations
  • IAM permissions for code signing operations

These omissions are intentional: the goal is to illustrate how code signing validation is wired, not provide drop-in security modules. See the Lambda CodeSigningConfig resource reference for all available configuration options.

Let's configure AWS Lambda Code Signing

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Policies & Enforcement
What's the difference between Enforce and Warn policies?
Enforce blocks deployment of unsigned or untrusted code, while Warn allows deployment but logs a warning. Use Enforce for production environments and Warn for development.
Configuration & Setup
Do I need to create signing profiles before the code signing config?
Yes, create aws.signer.SigningProfile resources first and reference their versionArn in the signingProfileVersionArns array.
Can I allow multiple signing profiles in one configuration?
Yes, provide multiple signing profile version ARNs in the signingProfileVersionArns array. This is useful for allowing different teams or environments to deploy.
Should I create separate code signing configs for different environments?
Yes, create separate configs with different policies: Enforce for production (strict validation) and Warn for development (flexible testing).
What platform should I use for Lambda signing profiles?
Use AWSLambda-SHA384-ECDSA as the platformId when creating signing profiles for Lambda functions.

Using a different cloud?

Explore security guides for other cloud providers: