Create and Configure KMS Keys

The aws:kms/key:Key resource, part of the Pulumi AWS provider, defines a KMS key for encryption, signing, or HMAC operations: its type, usage, policy, and regional scope. This guide focuses on four capabilities: symmetric encryption keys with automatic rotation, asymmetric keys for signing and HMAC generation, multi-Region key deployment, and inline vs standalone policy management.

Key policies reference IAM principals that must exist in your AWS account. The examples are intentionally small. Combine them with your own IAM roles, encryption targets, and access patterns.

Create a symmetric key with inline policy

Most encryption workflows start with a symmetric KMS key that encrypts data at rest, with a policy that controls administrative and cryptographic access.

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

const current = aws.getCallerIdentity({});
const example = new aws.kms.Key("example", {
    description: "An example symmetric encryption KMS key",
    enableKeyRotation: true,
    deletionWindowInDays: 20,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Id: "key-default-1",
        Statement: [
            {
                Sid: "Enable IAM User Permissions",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:root`),
                },
                Action: "kms:*",
                Resource: "*",
            },
            {
                Sid: "Allow administration of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:user/Alice`),
                },
                Action: [
                    "kms:ReplicateKey",
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                Resource: "*",
            },
            {
                Sid: "Allow use of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:user/Bob`),
                },
                Action: [
                    "kms:DescribeKey",
                    "kms:Encrypt",
                    "kms:Decrypt",
                    "kms:ReEncrypt*",
                    "kms:GenerateDataKey",
                    "kms:GenerateDataKeyWithoutPlaintext",
                ],
                Resource: "*",
            },
        ],
    }),
});
import pulumi
import json
import pulumi_aws as aws

current = aws.get_caller_identity()
example = aws.kms.Key("example",
    description="An example symmetric encryption KMS key",
    enable_key_rotation=True,
    deletion_window_in_days=20,
    policy=json.dumps({
        "Version": "2012-10-17",
        "Id": "key-default-1",
        "Statement": [
            {
                "Sid": "Enable IAM User Permissions",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:root",
                },
                "Action": "kms:*",
                "Resource": "*",
            },
            {
                "Sid": "Allow administration of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:user/Alice",
                },
                "Action": [
                    "kms:ReplicateKey",
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                "Resource": "*",
            },
            {
                "Sid": "Allow use of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:user/Bob",
                },
                "Action": [
                    "kms:DescribeKey",
                    "kms:Encrypt",
                    "kms:Decrypt",
                    "kms:ReEncrypt*",
                    "kms:GenerateDataKey",
                    "kms:GenerateDataKeyWithoutPlaintext",
                ],
                "Resource": "*",
            },
        ],
    }))
package main

import (
	"encoding/json"
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"Version": "2012-10-17",
			"Id":      "key-default-1",
			"Statement": []interface{}{
				map[string]interface{}{
					"Sid":    "Enable IAM User Permissions",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:root", current.AccountId),
					},
					"Action":   "kms:*",
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow administration of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:user/Alice", current.AccountId),
					},
					"Action": []string{
						"kms:ReplicateKey",
						"kms:Create*",
						"kms:Describe*",
						"kms:Enable*",
						"kms:List*",
						"kms:Put*",
						"kms:Update*",
						"kms:Revoke*",
						"kms:Disable*",
						"kms:Get*",
						"kms:Delete*",
						"kms:ScheduleKeyDeletion",
						"kms:CancelKeyDeletion",
					},
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow use of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:user/Bob", current.AccountId),
					},
					"Action": []string{
						"kms:DescribeKey",
						"kms:Encrypt",
						"kms:Decrypt",
						"kms:ReEncrypt*",
						"kms:GenerateDataKey",
						"kms:GenerateDataKeyWithoutPlaintext",
					},
					"Resource": "*",
				},
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:          pulumi.String("An example symmetric encryption KMS key"),
			EnableKeyRotation:    pulumi.Bool(true),
			DeletionWindowInDays: pulumi.Int(20),
			Policy:               pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var current = Aws.GetCallerIdentity.Invoke();

    var example = new Aws.Kms.Key("example", new()
    {
        Description = "An example symmetric encryption KMS key",
        EnableKeyRotation = true,
        DeletionWindowInDays = 20,
        Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["Version"] = "2012-10-17",
            ["Id"] = "key-default-1",
            ["Statement"] = new[]
            {
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Enable IAM User Permissions",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:root",
                    },
                    ["Action"] = "kms:*",
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow administration of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:user/Alice",
                    },
                    ["Action"] = new[]
                    {
                        "kms:ReplicateKey",
                        "kms:Create*",
                        "kms:Describe*",
                        "kms:Enable*",
                        "kms:List*",
                        "kms:Put*",
                        "kms:Update*",
                        "kms:Revoke*",
                        "kms:Disable*",
                        "kms:Get*",
                        "kms:Delete*",
                        "kms:ScheduleKeyDeletion",
                        "kms:CancelKeyDeletion",
                    },
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow use of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:user/Bob",
                    },
                    ["Action"] = new[]
                    {
                        "kms:DescribeKey",
                        "kms:Encrypt",
                        "kms:Decrypt",
                        "kms:ReEncrypt*",
                        "kms:GenerateDataKey",
                        "kms:GenerateDataKeyWithoutPlaintext",
                    },
                    ["Resource"] = "*",
                },
            },
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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) {
        final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        var example = new Key("example", KeyArgs.builder()
            .description("An example symmetric encryption KMS key")
            .enableKeyRotation(true)
            .deletionWindowInDays(20)
            .policy(serializeJson(
                jsonObject(
                    jsonProperty("Version", "2012-10-17"),
                    jsonProperty("Id", "key-default-1"),
                    jsonProperty("Statement", jsonArray(
                        jsonObject(
                            jsonProperty("Sid", "Enable IAM User Permissions"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:root", current.accountId()))
                            )),
                            jsonProperty("Action", "kms:*"),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow administration of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:user/Alice", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:ReplicateKey", 
                                "kms:Create*", 
                                "kms:Describe*", 
                                "kms:Enable*", 
                                "kms:List*", 
                                "kms:Put*", 
                                "kms:Update*", 
                                "kms:Revoke*", 
                                "kms:Disable*", 
                                "kms:Get*", 
                                "kms:Delete*", 
                                "kms:ScheduleKeyDeletion", 
                                "kms:CancelKeyDeletion"
                            )),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow use of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:user/Bob", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:DescribeKey", 
                                "kms:Encrypt", 
                                "kms:Decrypt", 
                                "kms:ReEncrypt*", 
                                "kms:GenerateDataKey", 
                                "kms:GenerateDataKeyWithoutPlaintext"
                            )),
                            jsonProperty("Resource", "*")
                        )
                    ))
                )))
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: An example symmetric encryption KMS key
      enableKeyRotation: true
      deletionWindowInDays: 20
      policy:
        fn::toJSON:
          Version: 2012-10-17
          Id: key-default-1
          Statement:
            - Sid: Enable IAM User Permissions
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:root
              Action: kms:*
              Resource: '*'
            - Sid: Allow administration of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:user/Alice
              Action:
                - kms:ReplicateKey
                - kms:Create*
                - kms:Describe*
                - kms:Enable*
                - kms:List*
                - kms:Put*
                - kms:Update*
                - kms:Revoke*
                - kms:Disable*
                - kms:Get*
                - kms:Delete*
                - kms:ScheduleKeyDeletion
                - kms:CancelKeyDeletion
              Resource: '*'
            - Sid: Allow use of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:user/Bob
              Action:
                - kms:DescribeKey
                - kms:Encrypt
                - kms:Decrypt
                - kms:ReEncrypt*
                - kms:GenerateDataKey
                - kms:GenerateDataKeyWithoutPlaintext
              Resource: '*'
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}

The policy property defines who can manage and use the key. The Principal field specifies IAM users, roles, or the account root. The Action field lists KMS operations each principal can perform. Setting enableKeyRotation to true makes AWS automatically rotate the key material annually. The deletionWindowInDays property sets a waiting period before AWS permanently deletes a key you’ve scheduled for deletion.

Manage key policy with a standalone resource

Teams that update key policies independently from the key itself can separate policy management into its own resource.

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

const current = aws.getCallerIdentity({});
const example = new aws.kms.Key("example", {
    description: "An example symmetric encryption KMS key",
    enableKeyRotation: true,
    deletionWindowInDays: 20,
});
const exampleKeyPolicy = new aws.kms.KeyPolicy("example", {
    keyId: example.id,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Id: "key-default-1",
        Statement: [{
            Sid: "Enable IAM User Permissions",
            Effect: "Allow",
            Principal: {
                AWS: current.then(current => `arn:aws:iam::${current.accountId}:root`),
            },
            Action: "kms:*",
            Resource: "*",
        }],
    }),
});
import pulumi
import json
import pulumi_aws as aws

current = aws.get_caller_identity()
example = aws.kms.Key("example",
    description="An example symmetric encryption KMS key",
    enable_key_rotation=True,
    deletion_window_in_days=20)
example_key_policy = aws.kms.KeyPolicy("example",
    key_id=example.id,
    policy=json.dumps({
        "Version": "2012-10-17",
        "Id": "key-default-1",
        "Statement": [{
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": f"arn:aws:iam::{current.account_id}:root",
            },
            "Action": "kms:*",
            "Resource": "*",
        }],
    }))
package main

import (
	"encoding/json"
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		example, err := kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:          pulumi.String("An example symmetric encryption KMS key"),
			EnableKeyRotation:    pulumi.Bool(true),
			DeletionWindowInDays: pulumi.Int(20),
		})
		if err != nil {
			return err
		}
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"Version": "2012-10-17",
			"Id":      "key-default-1",
			"Statement": []map[string]interface{}{
				map[string]interface{}{
					"Sid":    "Enable IAM User Permissions",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:root", current.AccountId),
					},
					"Action":   "kms:*",
					"Resource": "*",
				},
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = kms.NewKeyPolicy(ctx, "example", &kms.KeyPolicyArgs{
			KeyId:  example.ID(),
			Policy: pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var current = Aws.GetCallerIdentity.Invoke();

    var example = new Aws.Kms.Key("example", new()
    {
        Description = "An example symmetric encryption KMS key",
        EnableKeyRotation = true,
        DeletionWindowInDays = 20,
    });

    var exampleKeyPolicy = new Aws.Kms.KeyPolicy("example", new()
    {
        KeyId = example.Id,
        Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["Version"] = "2012-10-17",
            ["Id"] = "key-default-1",
            ["Statement"] = new[]
            {
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Enable IAM User Permissions",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:root",
                    },
                    ["Action"] = "kms:*",
                    ["Resource"] = "*",
                },
            },
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import com.pulumi.aws.kms.KeyPolicy;
import com.pulumi.aws.kms.KeyPolicyArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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) {
        final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        var example = new Key("example", KeyArgs.builder()
            .description("An example symmetric encryption KMS key")
            .enableKeyRotation(true)
            .deletionWindowInDays(20)
            .build());

        var exampleKeyPolicy = new KeyPolicy("exampleKeyPolicy", KeyPolicyArgs.builder()
            .keyId(example.id())
            .policy(serializeJson(
                jsonObject(
                    jsonProperty("Version", "2012-10-17"),
                    jsonProperty("Id", "key-default-1"),
                    jsonProperty("Statement", jsonArray(jsonObject(
                        jsonProperty("Sid", "Enable IAM User Permissions"),
                        jsonProperty("Effect", "Allow"),
                        jsonProperty("Principal", jsonObject(
                            jsonProperty("AWS", String.format("arn:aws:iam::%s:root", current.accountId()))
                        )),
                        jsonProperty("Action", "kms:*"),
                        jsonProperty("Resource", "*")
                    )))
                )))
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: An example symmetric encryption KMS key
      enableKeyRotation: true
      deletionWindowInDays: 20
  exampleKeyPolicy:
    type: aws:kms:KeyPolicy
    name: example
    properties:
      keyId: ${example.id}
      policy:
        fn::toJSON:
          Version: 2012-10-17
          Id: key-default-1
          Statement:
            - Sid: Enable IAM User Permissions
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:root
              Action: kms:*
              Resource: '*'
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}

The KeyPolicy resource references the key via keyId and manages the policy separately. This decouples policy updates from key lifecycle changes, allowing you to modify access control without touching the key resource itself.

Create an asymmetric key for signing

Applications that sign data or verify signatures use asymmetric keys with public/private key pairs.

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

const current = aws.getCallerIdentity({});
const example = new aws.kms.Key("example", {
    description: "RSA-3072 asymmetric KMS key for signing and verification",
    customerMasterKeySpec: "RSA_3072",
    keyUsage: "SIGN_VERIFY",
    enableKeyRotation: false,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Id: "key-default-1",
        Statement: [
            {
                Sid: "Enable IAM User Permissions",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:root`),
                },
                Action: "kms:*",
                Resource: "*",
            },
            {
                Sid: "Allow administration of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:role/Admin`),
                },
                Action: [
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                Resource: "*",
            },
            {
                Sid: "Allow use of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:role/Developer`),
                },
                Action: [
                    "kms:Sign",
                    "kms:Verify",
                    "kms:DescribeKey",
                ],
                Resource: "*",
            },
        ],
    }),
});
import pulumi
import json
import pulumi_aws as aws

current = aws.get_caller_identity()
example = aws.kms.Key("example",
    description="RSA-3072 asymmetric KMS key for signing and verification",
    customer_master_key_spec="RSA_3072",
    key_usage="SIGN_VERIFY",
    enable_key_rotation=False,
    policy=json.dumps({
        "Version": "2012-10-17",
        "Id": "key-default-1",
        "Statement": [
            {
                "Sid": "Enable IAM User Permissions",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:root",
                },
                "Action": "kms:*",
                "Resource": "*",
            },
            {
                "Sid": "Allow administration of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:role/Admin",
                },
                "Action": [
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                "Resource": "*",
            },
            {
                "Sid": "Allow use of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:role/Developer",
                },
                "Action": [
                    "kms:Sign",
                    "kms:Verify",
                    "kms:DescribeKey",
                ],
                "Resource": "*",
            },
        ],
    }))
package main

import (
	"encoding/json"
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"Version": "2012-10-17",
			"Id":      "key-default-1",
			"Statement": []interface{}{
				map[string]interface{}{
					"Sid":    "Enable IAM User Permissions",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:root", current.AccountId),
					},
					"Action":   "kms:*",
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow administration of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:role/Admin", current.AccountId),
					},
					"Action": []string{
						"kms:Create*",
						"kms:Describe*",
						"kms:Enable*",
						"kms:List*",
						"kms:Put*",
						"kms:Update*",
						"kms:Revoke*",
						"kms:Disable*",
						"kms:Get*",
						"kms:Delete*",
						"kms:ScheduleKeyDeletion",
						"kms:CancelKeyDeletion",
					},
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow use of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:role/Developer", current.AccountId),
					},
					"Action": []string{
						"kms:Sign",
						"kms:Verify",
						"kms:DescribeKey",
					},
					"Resource": "*",
				},
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:           pulumi.String("RSA-3072 asymmetric KMS key for signing and verification"),
			CustomerMasterKeySpec: pulumi.String("RSA_3072"),
			KeyUsage:              pulumi.String("SIGN_VERIFY"),
			EnableKeyRotation:     pulumi.Bool(false),
			Policy:                pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var current = Aws.GetCallerIdentity.Invoke();

    var example = new Aws.Kms.Key("example", new()
    {
        Description = "RSA-3072 asymmetric KMS key for signing and verification",
        CustomerMasterKeySpec = "RSA_3072",
        KeyUsage = "SIGN_VERIFY",
        EnableKeyRotation = false,
        Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["Version"] = "2012-10-17",
            ["Id"] = "key-default-1",
            ["Statement"] = new[]
            {
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Enable IAM User Permissions",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:root",
                    },
                    ["Action"] = "kms:*",
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow administration of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:role/Admin",
                    },
                    ["Action"] = new[]
                    {
                        "kms:Create*",
                        "kms:Describe*",
                        "kms:Enable*",
                        "kms:List*",
                        "kms:Put*",
                        "kms:Update*",
                        "kms:Revoke*",
                        "kms:Disable*",
                        "kms:Get*",
                        "kms:Delete*",
                        "kms:ScheduleKeyDeletion",
                        "kms:CancelKeyDeletion",
                    },
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow use of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:role/Developer",
                    },
                    ["Action"] = new[]
                    {
                        "kms:Sign",
                        "kms:Verify",
                        "kms:DescribeKey",
                    },
                    ["Resource"] = "*",
                },
            },
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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) {
        final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        var example = new Key("example", KeyArgs.builder()
            .description("RSA-3072 asymmetric KMS key for signing and verification")
            .customerMasterKeySpec("RSA_3072")
            .keyUsage("SIGN_VERIFY")
            .enableKeyRotation(false)
            .policy(serializeJson(
                jsonObject(
                    jsonProperty("Version", "2012-10-17"),
                    jsonProperty("Id", "key-default-1"),
                    jsonProperty("Statement", jsonArray(
                        jsonObject(
                            jsonProperty("Sid", "Enable IAM User Permissions"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:root", current.accountId()))
                            )),
                            jsonProperty("Action", "kms:*"),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow administration of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:role/Admin", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:Create*", 
                                "kms:Describe*", 
                                "kms:Enable*", 
                                "kms:List*", 
                                "kms:Put*", 
                                "kms:Update*", 
                                "kms:Revoke*", 
                                "kms:Disable*", 
                                "kms:Get*", 
                                "kms:Delete*", 
                                "kms:ScheduleKeyDeletion", 
                                "kms:CancelKeyDeletion"
                            )),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow use of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:role/Developer", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:Sign", 
                                "kms:Verify", 
                                "kms:DescribeKey"
                            )),
                            jsonProperty("Resource", "*")
                        )
                    ))
                )))
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: RSA-3072 asymmetric KMS key for signing and verification
      customerMasterKeySpec: RSA_3072
      keyUsage: SIGN_VERIFY
      enableKeyRotation: false
      policy:
        fn::toJSON:
          Version: 2012-10-17
          Id: key-default-1
          Statement:
            - Sid: Enable IAM User Permissions
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:root
              Action: kms:*
              Resource: '*'
            - Sid: Allow administration of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:role/Admin
              Action:
                - kms:Create*
                - kms:Describe*
                - kms:Enable*
                - kms:List*
                - kms:Put*
                - kms:Update*
                - kms:Revoke*
                - kms:Disable*
                - kms:Get*
                - kms:Delete*
                - kms:ScheduleKeyDeletion
                - kms:CancelKeyDeletion
              Resource: '*'
            - Sid: Allow use of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:role/Developer
              Action:
                - kms:Sign
                - kms:Verify
                - kms:DescribeKey
              Resource: '*'
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}

The customerMasterKeySpec property sets the key algorithm (RSA_3072 here). The keyUsage property specifies SIGN_VERIFY instead of the default ENCRYPT_DECRYPT. Asymmetric keys don’t support automatic rotation, so enableKeyRotation must be false. The policy grants Sign and Verify actions instead of Encrypt and Decrypt.

Generate HMAC tokens for authentication

HMAC keys produce message authentication codes for verifying data integrity without encryption.

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

const current = aws.getCallerIdentity({});
const example = new aws.kms.Key("example", {
    description: "HMAC_384 key for tokens",
    customerMasterKeySpec: "HMAC_384",
    keyUsage: "GENERATE_VERIFY_MAC",
    enableKeyRotation: false,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Id: "key-default-1",
        Statement: [
            {
                Sid: "Enable IAM User Permissions",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:root`),
                },
                Action: "kms:*",
                Resource: "*",
            },
            {
                Sid: "Allow administration of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:role/Admin`),
                },
                Action: [
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                Resource: "*",
            },
            {
                Sid: "Allow use of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:role/Developer`),
                },
                Action: [
                    "kms:GenerateMac",
                    "kms:VerifyMac",
                    "kms:DescribeKey",
                ],
                Resource: "*",
            },
        ],
    }),
});
import pulumi
import json
import pulumi_aws as aws

current = aws.get_caller_identity()
example = aws.kms.Key("example",
    description="HMAC_384 key for tokens",
    customer_master_key_spec="HMAC_384",
    key_usage="GENERATE_VERIFY_MAC",
    enable_key_rotation=False,
    policy=json.dumps({
        "Version": "2012-10-17",
        "Id": "key-default-1",
        "Statement": [
            {
                "Sid": "Enable IAM User Permissions",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:root",
                },
                "Action": "kms:*",
                "Resource": "*",
            },
            {
                "Sid": "Allow administration of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:role/Admin",
                },
                "Action": [
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                "Resource": "*",
            },
            {
                "Sid": "Allow use of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:role/Developer",
                },
                "Action": [
                    "kms:GenerateMac",
                    "kms:VerifyMac",
                    "kms:DescribeKey",
                ],
                "Resource": "*",
            },
        ],
    }))
package main

import (
	"encoding/json"
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"Version": "2012-10-17",
			"Id":      "key-default-1",
			"Statement": []interface{}{
				map[string]interface{}{
					"Sid":    "Enable IAM User Permissions",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:root", current.AccountId),
					},
					"Action":   "kms:*",
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow administration of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:role/Admin", current.AccountId),
					},
					"Action": []string{
						"kms:Create*",
						"kms:Describe*",
						"kms:Enable*",
						"kms:List*",
						"kms:Put*",
						"kms:Update*",
						"kms:Revoke*",
						"kms:Disable*",
						"kms:Get*",
						"kms:Delete*",
						"kms:ScheduleKeyDeletion",
						"kms:CancelKeyDeletion",
					},
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow use of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:role/Developer", current.AccountId),
					},
					"Action": []string{
						"kms:GenerateMac",
						"kms:VerifyMac",
						"kms:DescribeKey",
					},
					"Resource": "*",
				},
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:           pulumi.String("HMAC_384 key for tokens"),
			CustomerMasterKeySpec: pulumi.String("HMAC_384"),
			KeyUsage:              pulumi.String("GENERATE_VERIFY_MAC"),
			EnableKeyRotation:     pulumi.Bool(false),
			Policy:                pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var current = Aws.GetCallerIdentity.Invoke();

    var example = new Aws.Kms.Key("example", new()
    {
        Description = "HMAC_384 key for tokens",
        CustomerMasterKeySpec = "HMAC_384",
        KeyUsage = "GENERATE_VERIFY_MAC",
        EnableKeyRotation = false,
        Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["Version"] = "2012-10-17",
            ["Id"] = "key-default-1",
            ["Statement"] = new[]
            {
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Enable IAM User Permissions",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:root",
                    },
                    ["Action"] = "kms:*",
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow administration of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:role/Admin",
                    },
                    ["Action"] = new[]
                    {
                        "kms:Create*",
                        "kms:Describe*",
                        "kms:Enable*",
                        "kms:List*",
                        "kms:Put*",
                        "kms:Update*",
                        "kms:Revoke*",
                        "kms:Disable*",
                        "kms:Get*",
                        "kms:Delete*",
                        "kms:ScheduleKeyDeletion",
                        "kms:CancelKeyDeletion",
                    },
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow use of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:role/Developer",
                    },
                    ["Action"] = new[]
                    {
                        "kms:GenerateMac",
                        "kms:VerifyMac",
                        "kms:DescribeKey",
                    },
                    ["Resource"] = "*",
                },
            },
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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) {
        final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        var example = new Key("example", KeyArgs.builder()
            .description("HMAC_384 key for tokens")
            .customerMasterKeySpec("HMAC_384")
            .keyUsage("GENERATE_VERIFY_MAC")
            .enableKeyRotation(false)
            .policy(serializeJson(
                jsonObject(
                    jsonProperty("Version", "2012-10-17"),
                    jsonProperty("Id", "key-default-1"),
                    jsonProperty("Statement", jsonArray(
                        jsonObject(
                            jsonProperty("Sid", "Enable IAM User Permissions"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:root", current.accountId()))
                            )),
                            jsonProperty("Action", "kms:*"),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow administration of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:role/Admin", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:Create*", 
                                "kms:Describe*", 
                                "kms:Enable*", 
                                "kms:List*", 
                                "kms:Put*", 
                                "kms:Update*", 
                                "kms:Revoke*", 
                                "kms:Disable*", 
                                "kms:Get*", 
                                "kms:Delete*", 
                                "kms:ScheduleKeyDeletion", 
                                "kms:CancelKeyDeletion"
                            )),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow use of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:role/Developer", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:GenerateMac", 
                                "kms:VerifyMac", 
                                "kms:DescribeKey"
                            )),
                            jsonProperty("Resource", "*")
                        )
                    ))
                )))
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: HMAC_384 key for tokens
      customerMasterKeySpec: HMAC_384
      keyUsage: GENERATE_VERIFY_MAC
      enableKeyRotation: false
      policy:
        fn::toJSON:
          Version: 2012-10-17
          Id: key-default-1
          Statement:
            - Sid: Enable IAM User Permissions
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:root
              Action: kms:*
              Resource: '*'
            - Sid: Allow administration of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:role/Admin
              Action:
                - kms:Create*
                - kms:Describe*
                - kms:Enable*
                - kms:List*
                - kms:Put*
                - kms:Update*
                - kms:Revoke*
                - kms:Disable*
                - kms:Get*
                - kms:Delete*
                - kms:ScheduleKeyDeletion
                - kms:CancelKeyDeletion
              Resource: '*'
            - Sid: Allow use of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:role/Developer
              Action:
                - kms:GenerateMac
                - kms:VerifyMac
                - kms:DescribeKey
              Resource: '*'
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}

The customerMasterKeySpec property specifies HMAC_384 for the hash algorithm. The keyUsage property sets GENERATE_VERIFY_MAC. The policy grants GenerateMac and VerifyMac actions. Like asymmetric keys, HMAC keys don’t support automatic rotation.

Deploy a multi-Region primary key

Applications operating across multiple AWS regions can use multi-Region keys to encrypt data with the same key material in different regions.

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

const current = aws.getCallerIdentity({});
const example = new aws.kms.Key("example", {
    description: "An example multi-Region primary key",
    multiRegion: true,
    enableKeyRotation: true,
    deletionWindowInDays: 10,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Id: "key-default-1",
        Statement: [
            {
                Sid: "Enable IAM User Permissions",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:root`),
                },
                Action: "kms:*",
                Resource: "*",
            },
            {
                Sid: "Allow administration of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:user/Alice`),
                },
                Action: [
                    "kms:ReplicateKey",
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                Resource: "*",
            },
            {
                Sid: "Allow use of the key",
                Effect: "Allow",
                Principal: {
                    AWS: current.then(current => `arn:aws:iam::${current.accountId}:user/Bob`),
                },
                Action: [
                    "kms:DescribeKey",
                    "kms:Encrypt",
                    "kms:Decrypt",
                    "kms:ReEncrypt*",
                    "kms:GenerateDataKey",
                    "kms:GenerateDataKeyWithoutPlaintext",
                ],
                Resource: "*",
            },
        ],
    }),
});
import pulumi
import json
import pulumi_aws as aws

current = aws.get_caller_identity()
example = aws.kms.Key("example",
    description="An example multi-Region primary key",
    multi_region=True,
    enable_key_rotation=True,
    deletion_window_in_days=10,
    policy=json.dumps({
        "Version": "2012-10-17",
        "Id": "key-default-1",
        "Statement": [
            {
                "Sid": "Enable IAM User Permissions",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:root",
                },
                "Action": "kms:*",
                "Resource": "*",
            },
            {
                "Sid": "Allow administration of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:user/Alice",
                },
                "Action": [
                    "kms:ReplicateKey",
                    "kms:Create*",
                    "kms:Describe*",
                    "kms:Enable*",
                    "kms:List*",
                    "kms:Put*",
                    "kms:Update*",
                    "kms:Revoke*",
                    "kms:Disable*",
                    "kms:Get*",
                    "kms:Delete*",
                    "kms:ScheduleKeyDeletion",
                    "kms:CancelKeyDeletion",
                ],
                "Resource": "*",
            },
            {
                "Sid": "Allow use of the key",
                "Effect": "Allow",
                "Principal": {
                    "AWS": f"arn:aws:iam::{current.account_id}:user/Bob",
                },
                "Action": [
                    "kms:DescribeKey",
                    "kms:Encrypt",
                    "kms:Decrypt",
                    "kms:ReEncrypt*",
                    "kms:GenerateDataKey",
                    "kms:GenerateDataKeyWithoutPlaintext",
                ],
                "Resource": "*",
            },
        ],
    }))
package main

import (
	"encoding/json"
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"Version": "2012-10-17",
			"Id":      "key-default-1",
			"Statement": []interface{}{
				map[string]interface{}{
					"Sid":    "Enable IAM User Permissions",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:root", current.AccountId),
					},
					"Action":   "kms:*",
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow administration of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:user/Alice", current.AccountId),
					},
					"Action": []string{
						"kms:ReplicateKey",
						"kms:Create*",
						"kms:Describe*",
						"kms:Enable*",
						"kms:List*",
						"kms:Put*",
						"kms:Update*",
						"kms:Revoke*",
						"kms:Disable*",
						"kms:Get*",
						"kms:Delete*",
						"kms:ScheduleKeyDeletion",
						"kms:CancelKeyDeletion",
					},
					"Resource": "*",
				},
				map[string]interface{}{
					"Sid":    "Allow use of the key",
					"Effect": "Allow",
					"Principal": map[string]interface{}{
						"AWS": fmt.Sprintf("arn:aws:iam::%v:user/Bob", current.AccountId),
					},
					"Action": []string{
						"kms:DescribeKey",
						"kms:Encrypt",
						"kms:Decrypt",
						"kms:ReEncrypt*",
						"kms:GenerateDataKey",
						"kms:GenerateDataKeyWithoutPlaintext",
					},
					"Resource": "*",
				},
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		_, err = kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:          pulumi.String("An example multi-Region primary key"),
			MultiRegion:          pulumi.Bool(true),
			EnableKeyRotation:    pulumi.Bool(true),
			DeletionWindowInDays: pulumi.Int(10),
			Policy:               pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var current = Aws.GetCallerIdentity.Invoke();

    var example = new Aws.Kms.Key("example", new()
    {
        Description = "An example multi-Region primary key",
        MultiRegion = true,
        EnableKeyRotation = true,
        DeletionWindowInDays = 10,
        Policy = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["Version"] = "2012-10-17",
            ["Id"] = "key-default-1",
            ["Statement"] = new[]
            {
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Enable IAM User Permissions",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:root",
                    },
                    ["Action"] = "kms:*",
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow administration of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:user/Alice",
                    },
                    ["Action"] = new[]
                    {
                        "kms:ReplicateKey",
                        "kms:Create*",
                        "kms:Describe*",
                        "kms:Enable*",
                        "kms:List*",
                        "kms:Put*",
                        "kms:Update*",
                        "kms:Revoke*",
                        "kms:Disable*",
                        "kms:Get*",
                        "kms:Delete*",
                        "kms:ScheduleKeyDeletion",
                        "kms:CancelKeyDeletion",
                    },
                    ["Resource"] = "*",
                },
                new Dictionary<string, object?>
                {
                    ["Sid"] = "Allow use of the key",
                    ["Effect"] = "Allow",
                    ["Principal"] = new Dictionary<string, object?>
                    {
                        ["AWS"] = $"arn:aws:iam::{current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId)}:user/Bob",
                    },
                    ["Action"] = new[]
                    {
                        "kms:DescribeKey",
                        "kms:Encrypt",
                        "kms:Decrypt",
                        "kms:ReEncrypt*",
                        "kms:GenerateDataKey",
                        "kms:GenerateDataKeyWithoutPlaintext",
                    },
                    ["Resource"] = "*",
                },
            },
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import static com.pulumi.codegen.internal.Serialization.*;
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) {
        final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        var example = new Key("example", KeyArgs.builder()
            .description("An example multi-Region primary key")
            .multiRegion(true)
            .enableKeyRotation(true)
            .deletionWindowInDays(10)
            .policy(serializeJson(
                jsonObject(
                    jsonProperty("Version", "2012-10-17"),
                    jsonProperty("Id", "key-default-1"),
                    jsonProperty("Statement", jsonArray(
                        jsonObject(
                            jsonProperty("Sid", "Enable IAM User Permissions"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:root", current.accountId()))
                            )),
                            jsonProperty("Action", "kms:*"),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow administration of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:user/Alice", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:ReplicateKey", 
                                "kms:Create*", 
                                "kms:Describe*", 
                                "kms:Enable*", 
                                "kms:List*", 
                                "kms:Put*", 
                                "kms:Update*", 
                                "kms:Revoke*", 
                                "kms:Disable*", 
                                "kms:Get*", 
                                "kms:Delete*", 
                                "kms:ScheduleKeyDeletion", 
                                "kms:CancelKeyDeletion"
                            )),
                            jsonProperty("Resource", "*")
                        ), 
                        jsonObject(
                            jsonProperty("Sid", "Allow use of the key"),
                            jsonProperty("Effect", "Allow"),
                            jsonProperty("Principal", jsonObject(
                                jsonProperty("AWS", String.format("arn:aws:iam::%s:user/Bob", current.accountId()))
                            )),
                            jsonProperty("Action", jsonArray(
                                "kms:DescribeKey", 
                                "kms:Encrypt", 
                                "kms:Decrypt", 
                                "kms:ReEncrypt*", 
                                "kms:GenerateDataKey", 
                                "kms:GenerateDataKeyWithoutPlaintext"
                            )),
                            jsonProperty("Resource", "*")
                        )
                    ))
                )))
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: An example multi-Region primary key
      multiRegion: true
      enableKeyRotation: true
      deletionWindowInDays: 10
      policy:
        fn::toJSON:
          Version: 2012-10-17
          Id: key-default-1
          Statement:
            - Sid: Enable IAM User Permissions
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:root
              Action: kms:*
              Resource: '*'
            - Sid: Allow administration of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:user/Alice
              Action:
                - kms:ReplicateKey
                - kms:Create*
                - kms:Describe*
                - kms:Enable*
                - kms:List*
                - kms:Put*
                - kms:Update*
                - kms:Revoke*
                - kms:Disable*
                - kms:Get*
                - kms:Delete*
                - kms:ScheduleKeyDeletion
                - kms:CancelKeyDeletion
              Resource: '*'
            - Sid: Allow use of the key
              Effect: Allow
              Principal:
                AWS: arn:aws:iam::${current.accountId}:user/Bob
              Action:
                - kms:DescribeKey
                - kms:Encrypt
                - kms:Decrypt
                - kms:ReEncrypt*
                - kms:GenerateDataKey
                - kms:GenerateDataKeyWithoutPlaintext
              Resource: '*'
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}

The multiRegion property creates a primary key that can be replicated to other regions. The policy includes the ReplicateKey action, allowing administrators to create replica keys. Multi-Region keys support automatic rotation when enableKeyRotation is true. After creating the primary key, you replicate it to other regions using a separate resource.

Beyond these examples

These snippets focus on specific key-level features: symmetric and asymmetric key types, inline and standalone policy management, and multi-Region key deployment. They’re intentionally minimal rather than full encryption solutions.

The examples reference pre-existing infrastructure such as IAM users and roles in key policies. They focus on configuring the key rather than provisioning the surrounding IAM infrastructure.

To keep things focused, common key patterns are omitted, including:

  • Custom key stores and CloudHSM integration (customKeyStoreId)
  • External key material (xksKeyId)
  • Key rotation period customization (rotationPeriodInDays)
  • Key disabling and re-enabling (isEnabled)

These omissions are intentional: the goal is to illustrate how each key feature is wired, not provide drop-in encryption modules. See the KMS Key resource reference for all available configuration options.

Let's create and Configure KMS Keys

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Key Policy & Access Control
Should I use the policy parameter or the aws.kms.KeyPolicy resource?
Choose one approach, not both. Configuring the key policy in both the policy parameter of aws.kms.Key and the standalone aws.kms.KeyPolicy resource will cause inconsistencies and may overwrite configuration.
What happens if I don't specify a key policy?
AWS gives the KMS key a default policy that grants all principals in the owning account unlimited access to all KMS operations for the key. This default policy effectively delegates all access control to IAM policies and KMS grants. Always specify an explicit key policy to control access.
What does bypassPolicyLockoutSafetyCheck do?
Setting bypassPolicyLockoutSafetyCheck to true increases the risk that the KMS key becomes unmanageable. Do not set this value to true indiscriminately. The default is false.
Key Types & Configuration
How do I create a symmetric encryption KMS key?
Use the default values: customerMasterKeySpec defaults to SYMMETRIC_DEFAULT and keyUsage defaults to ENCRYPT_DECRYPT. Set enableKeyRotation: true to enable automatic key rotation.
How do I create an asymmetric KMS key for signing?
Set customerMasterKeySpec to an RSA or ECC value (e.g., RSA_3072) and keyUsage to SIGN_VERIFY. Set enableKeyRotation: false because rotation is not supported for asymmetric keys.
How do I create an HMAC key for token generation?
Set customerMasterKeySpec to an HMAC value (e.g., HMAC_384) and keyUsage to GENERATE_VERIFY_MAC. Set enableKeyRotation: false because rotation is not supported for HMAC keys.
What properties are immutable after creating a KMS key?
The following properties cannot be changed after key creation: multiRegion, customerMasterKeySpec, keyUsage, customKeyStoreId, and xksKeyId. Changing these requires creating a new key.
Key Rotation
Can I enable key rotation for all key types?
No. Key rotation can only be enabled for symmetric encryption keys (SYMMETRIC_DEFAULT). Asymmetric keys (RSA, ECC) and HMAC keys do not support automatic rotation, as shown in the examples where enableKeyRotation: false is set for these key types.
What are the limits for custom rotation periods?
The rotationPeriodInDays must be between 90 and 2560 days (inclusive).
Multi-Region Keys
How do I create a multi-Region primary key?
Set multiRegion: true. You can enable key rotation with enableKeyRotation: true. Include the kms:ReplicateKey permission in the key policy for administrators who need to create replica keys.
When does the deletion window start for multi-Region primary keys?
For multi-Region primary keys with replicas, the deletion waiting period begins when the last replica key is deleted. For other keys, the waiting period begins immediately.
Deletion & Lifecycle
What are the deletion window limits for KMS keys?
The deletionWindowInDays must be between 7 and 30 days (inclusive). If not specified, it defaults to 30 days.

Using a different cloud?

Explore encryption guides for other cloud providers: