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, rotation settings, and access policy. This guide focuses on four capabilities: symmetric encryption keys with automatic rotation, asymmetric keys for signing and HMAC generation, multi-Region key deployment, and policy management approaches.

KMS keys require policies that grant access to IAM principals. The examples are intentionally small. Combine them with your own IAM users, roles, and service integrations.

Create a symmetric encryption key with inline policy

Most encryption workflows start with a symmetric key that encrypts data at rest, with a policy controlling who can administer and use it.

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 a JSON document with three statements: root account permissions, administrative actions for specific users, and encryption operations for others. The enableKeyRotation property triggers automatic key material rotation annually. The deletionWindowInDays property sets a 20-day waiting period before AWS deletes the key, allowing recovery from accidental deletion.

Manage key policy with a standalone resource

Teams that update access controls frequently can separate the policy into its own resource, allowing policy changes without modifying the key.

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 independently. This separation lets you update access controls without triggering key recreation or affecting other key properties like rotation settings.

Create an asymmetric key for signing operations

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 for 3072-bit RSA keys). The keyUsage property restricts operations to SIGN_VERIFY, preventing encryption use. Asymmetric keys cannot enable automatic rotation; you must manually rotate them by creating new keys.

Generate HMAC keys for message authentication

Systems that verify message integrity without encryption use HMAC keys to generate and verify authentication codes.

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 384-bit HMAC keys. The keyUsage property limits operations to GENERATE_VERIFY_MAC. The policy grants GenerateMac and VerifyMac actions to specific roles, controlling who can create and validate authentication codes.

Deploy a multi-Region primary key for global encryption

Applications operating across 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 ReplicateKey action for administrators, allowing them to create replica keys. Multi-Region keys support automatic rotation, with rotation synchronized across all replicas.

Beyond these examples

These snippets focus on specific KMS key features: symmetric and asymmetric key types, key policy management (inline and standalone), 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 structure.

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 state management (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 & Permissions
Can I configure the key policy in both the Key resource and KeyPolicy resource?
No, you should choose one approach. Configuring the policy in both aws.kms.Key (using the policy parameter) and aws.kms.KeyPolicy resource will cause inconsistencies and may overwrite your configuration.
What happens if I don't specify a key policy?
AWS applies a default policy that gives all principals in your account unlimited access to all KMS operations. This default policy effectively delegates all access control to IAM policies and KMS grants, which may not be what you want for security.
Can I use aws.iam.getPolicyDocument for my key policy?
Yes, although this is a key policy (not an IAM policy), you can use aws.iam.getPolicyDocument in the form that designates a principal.
What does bypassPolicyLockoutSafetyCheck do?
Setting this to true bypasses the safety check that prevents you from locking yourself out of the key. This increases the risk that the key becomes unmanageable, so don’t enable it indiscriminately.
Key Types & Specifications
What's the difference between symmetric and asymmetric KMS keys?
Symmetric keys (default, SYMMETRIC_DEFAULT) use the same key for encryption and decryption. Asymmetric keys use key pairs (public/private) for operations like signing/verification or encryption/decryption, specified via customerMasterKeySpec (e.g., RSA_3072, ECC_NIST_P256).
How do I create an asymmetric key for signing and verification?
Set customerMasterKeySpec to an RSA or ECC value (e.g., RSA_3072) and keyUsage to SIGN_VERIFY. You must also set enableKeyRotation to false since rotation isn’t supported for asymmetric keys.
How do I create an HMAC key for generating and verifying MACs?
Set customerMasterKeySpec to an HMAC value (e.g., HMAC_384) and keyUsage to GENERATE_VERIFY_MAC. Set enableKeyRotation to false since HMAC keys don’t support automatic rotation.
How do I create a multi-region KMS key?
Set multiRegion to true when creating the key. This creates a multi-region primary key that can be replicated to other regions. Include kms:ReplicateKey permission in your key policy for administrators.
Key Rotation
Can I enable automatic key rotation for all key types?
No, automatic key rotation (enableKeyRotation) is only supported for symmetric encryption keys (SYMMETRIC_DEFAULT). Asymmetric keys and HMAC keys don’t support automatic rotation.
How do I configure the key rotation period?
Use rotationPeriodInDays to set a custom rotation period between 90 and 2560 days (inclusive). The default rotation period is 365 days if you enable rotation without specifying this parameter.
Deletion & Lifecycle
What's the deletion window for KMS keys?
The deletion window is 7 to 30 days (defaults to 30). For multi-region primary keys with replicas, the waiting period begins when the last replica key is deleted. Otherwise, it begins immediately.
Immutable Properties
What properties can't I change after creating a KMS key?
These properties are immutable: multiRegion, customerMasterKeySpec, keyUsage, customKeyStoreId, and xksKeyId. Changing any of these requires creating a new key.

Using a different cloud?

Explore encryption guides for other cloud providers: