The aws:kms/customKeyStore:CustomKeyStore resource, part of the Pulumi AWS provider, defines a KMS custom key store that delegates cryptographic operations to CloudHSM clusters or external key management systems. This guide focuses on two capabilities: CloudHSM cluster integration and external key store connectivity via VPC or public endpoints.
Custom key stores require either CloudHSM clusters with trust anchor certificates or external XKS proxy endpoints with authentication credentials. The examples are intentionally small. Combine them with your own key management infrastructure and security policies.
Connect KMS to a CloudHSM cluster
Organizations with strict key management requirements use CloudHSM to maintain physical control over cryptographic operations, bridging KMS APIs with CloudHSM hardware.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as std from "@pulumi/std";
const test = new aws.kms.CustomKeyStore("test", {
cloudHsmClusterId: cloudHsmClusterId,
customKeyStoreName: "kms-custom-key-store-test",
keyStorePassword: "noplaintextpasswords1",
trustAnchorCertificate: std.file({
input: "anchor-certificate.crt",
}).then(invoke => invoke.result),
});
import pulumi
import pulumi_aws as aws
import pulumi_std as std
test = aws.kms.CustomKeyStore("test",
cloud_hsm_cluster_id=cloud_hsm_cluster_id,
custom_key_store_name="kms-custom-key-store-test",
key_store_password="noplaintextpasswords1",
trust_anchor_certificate=std.file(input="anchor-certificate.crt").result)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
invokeFile, err := std.File(ctx, &std.FileArgs{
Input: "anchor-certificate.crt",
}, nil)
if err != nil {
return err
}
_, err = kms.NewCustomKeyStore(ctx, "test", &kms.CustomKeyStoreArgs{
CloudHsmClusterId: pulumi.Any(cloudHsmClusterId),
CustomKeyStoreName: pulumi.String("kms-custom-key-store-test"),
KeyStorePassword: pulumi.String("noplaintextpasswords1"),
TrustAnchorCertificate: pulumi.String(invokeFile.Result),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var test = new Aws.Kms.CustomKeyStore("test", new()
{
CloudHsmClusterId = cloudHsmClusterId,
CustomKeyStoreName = "kms-custom-key-store-test",
KeyStorePassword = "noplaintextpasswords1",
TrustAnchorCertificate = Std.File.Invoke(new()
{
Input = "anchor-certificate.crt",
}).Apply(invoke => invoke.Result),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kms.CustomKeyStore;
import com.pulumi.aws.kms.CustomKeyStoreArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.FileArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var test = new CustomKeyStore("test", CustomKeyStoreArgs.builder()
.cloudHsmClusterId(cloudHsmClusterId)
.customKeyStoreName("kms-custom-key-store-test")
.keyStorePassword("noplaintextpasswords1")
.trustAnchorCertificate(StdFunctions.file(FileArgs.builder()
.input("anchor-certificate.crt")
.build()).result())
.build());
}
}
resources:
test:
type: aws:kms:CustomKeyStore
properties:
cloudHsmClusterId: ${cloudHsmClusterId}
customKeyStoreName: kms-custom-key-store-test
keyStorePassword: noplaintextpasswords1
trustAnchorCertificate:
fn::invoke:
function: std:file
arguments:
input: anchor-certificate.crt
return: result
The cloudHsmClusterId property links the custom key store to your CloudHSM cluster. The trustAnchorCertificate property provides the cluster’s certificate chain, establishing trust between KMS and CloudHSM. The keyStorePassword authenticates KMS to the cluster’s crypto user account.
Connect to an external key manager via VPC endpoint
Some organizations maintain key management systems outside AWS and need KMS to delegate operations over private network connections.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.kms.CustomKeyStore("example", {
customKeyStoreName: "example-vpc-xks",
customKeyStoreType: "EXTERNAL_KEY_STORE",
xksProxyAuthenticationCredential: {
accessKeyId: ephemeralAccessKeyId,
rawSecretAccessKey: ephemeralSecretAccessKey,
},
xksProxyConnectivity: "VPC_ENDPOINT_SERVICE",
xksProxyUriEndpoint: "https://myproxy-private.xks.example.com",
xksProxyUriPath: "/kms/xks/v1",
xksProxyVpcEndpointServiceName: "com.amazonaws.vpce.us-east-1.vpce-svc-example",
});
import pulumi
import pulumi_aws as aws
example = aws.kms.CustomKeyStore("example",
custom_key_store_name="example-vpc-xks",
custom_key_store_type="EXTERNAL_KEY_STORE",
xks_proxy_authentication_credential={
"access_key_id": ephemeral_access_key_id,
"raw_secret_access_key": ephemeral_secret_access_key,
},
xks_proxy_connectivity="VPC_ENDPOINT_SERVICE",
xks_proxy_uri_endpoint="https://myproxy-private.xks.example.com",
xks_proxy_uri_path="/kms/xks/v1",
xks_proxy_vpc_endpoint_service_name="com.amazonaws.vpce.us-east-1.vpce-svc-example")
package main
import (
"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 {
_, err := kms.NewCustomKeyStore(ctx, "example", &kms.CustomKeyStoreArgs{
CustomKeyStoreName: pulumi.String("example-vpc-xks"),
CustomKeyStoreType: pulumi.String("EXTERNAL_KEY_STORE"),
XksProxyAuthenticationCredential: &kms.CustomKeyStoreXksProxyAuthenticationCredentialArgs{
AccessKeyId: pulumi.Any(ephemeralAccessKeyId),
RawSecretAccessKey: pulumi.Any(ephemeralSecretAccessKey),
},
XksProxyConnectivity: pulumi.String("VPC_ENDPOINT_SERVICE"),
XksProxyUriEndpoint: pulumi.String("https://myproxy-private.xks.example.com"),
XksProxyUriPath: pulumi.String("/kms/xks/v1"),
XksProxyVpcEndpointServiceName: pulumi.String("com.amazonaws.vpce.us-east-1.vpce-svc-example"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.Kms.CustomKeyStore("example", new()
{
CustomKeyStoreName = "example-vpc-xks",
CustomKeyStoreType = "EXTERNAL_KEY_STORE",
XksProxyAuthenticationCredential = new Aws.Kms.Inputs.CustomKeyStoreXksProxyAuthenticationCredentialArgs
{
AccessKeyId = ephemeralAccessKeyId,
RawSecretAccessKey = ephemeralSecretAccessKey,
},
XksProxyConnectivity = "VPC_ENDPOINT_SERVICE",
XksProxyUriEndpoint = "https://myproxy-private.xks.example.com",
XksProxyUriPath = "/kms/xks/v1",
XksProxyVpcEndpointServiceName = "com.amazonaws.vpce.us-east-1.vpce-svc-example",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kms.CustomKeyStore;
import com.pulumi.aws.kms.CustomKeyStoreArgs;
import com.pulumi.aws.kms.inputs.CustomKeyStoreXksProxyAuthenticationCredentialArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new CustomKeyStore("example", CustomKeyStoreArgs.builder()
.customKeyStoreName("example-vpc-xks")
.customKeyStoreType("EXTERNAL_KEY_STORE")
.xksProxyAuthenticationCredential(CustomKeyStoreXksProxyAuthenticationCredentialArgs.builder()
.accessKeyId(ephemeralAccessKeyId)
.rawSecretAccessKey(ephemeralSecretAccessKey)
.build())
.xksProxyConnectivity("VPC_ENDPOINT_SERVICE")
.xksProxyUriEndpoint("https://myproxy-private.xks.example.com")
.xksProxyUriPath("/kms/xks/v1")
.xksProxyVpcEndpointServiceName("com.amazonaws.vpce.us-east-1.vpce-svc-example")
.build());
}
}
resources:
example:
type: aws:kms:CustomKeyStore
properties:
customKeyStoreName: example-vpc-xks
customKeyStoreType: EXTERNAL_KEY_STORE
xksProxyAuthenticationCredential:
accessKeyId: ${ephemeralAccessKeyId}
rawSecretAccessKey: ${ephemeralSecretAccessKey}
xksProxyConnectivity: VPC_ENDPOINT_SERVICE
xksProxyUriEndpoint: https://myproxy-private.xks.example.com
xksProxyUriPath: /kms/xks/v1
xksProxyVpcEndpointServiceName: com.amazonaws.vpce.us-east-1.vpce-svc-example
The customKeyStoreType property set to EXTERNAL_KEY_STORE enables integration with third-party key managers. The xksProxyConnectivity property set to VPC_ENDPOINT_SERVICE routes traffic through a private VPC endpoint service. The xksProxyAuthenticationCredential property provides access credentials for the external proxy, while xksProxyUriEndpoint and xksProxyUriPath define the proxy’s location and API path.
Connect to an external key manager via public endpoint
When private connectivity isn’t required, external key stores can communicate with key management systems over public internet endpoints.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.kms.CustomKeyStore("example", {
customKeyStoreName: "example-public-xks",
customKeyStoreType: "EXTERNAL_KEY_STORE",
xksProxyAuthenticationCredential: {
accessKeyId: ephemeralAccessKeyId,
rawSecretAccessKey: ephemeralSecretAccessKey,
},
xksProxyConnectivity: "PUBLIC_ENDPOINT",
xksProxyUriEndpoint: "https://myproxy.xks.example.com",
xksProxyUriPath: "/kms/xks/v1",
});
import pulumi
import pulumi_aws as aws
example = aws.kms.CustomKeyStore("example",
custom_key_store_name="example-public-xks",
custom_key_store_type="EXTERNAL_KEY_STORE",
xks_proxy_authentication_credential={
"access_key_id": ephemeral_access_key_id,
"raw_secret_access_key": ephemeral_secret_access_key,
},
xks_proxy_connectivity="PUBLIC_ENDPOINT",
xks_proxy_uri_endpoint="https://myproxy.xks.example.com",
xks_proxy_uri_path="/kms/xks/v1")
package main
import (
"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 {
_, err := kms.NewCustomKeyStore(ctx, "example", &kms.CustomKeyStoreArgs{
CustomKeyStoreName: pulumi.String("example-public-xks"),
CustomKeyStoreType: pulumi.String("EXTERNAL_KEY_STORE"),
XksProxyAuthenticationCredential: &kms.CustomKeyStoreXksProxyAuthenticationCredentialArgs{
AccessKeyId: pulumi.Any(ephemeralAccessKeyId),
RawSecretAccessKey: pulumi.Any(ephemeralSecretAccessKey),
},
XksProxyConnectivity: pulumi.String("PUBLIC_ENDPOINT"),
XksProxyUriEndpoint: pulumi.String("https://myproxy.xks.example.com"),
XksProxyUriPath: pulumi.String("/kms/xks/v1"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.Kms.CustomKeyStore("example", new()
{
CustomKeyStoreName = "example-public-xks",
CustomKeyStoreType = "EXTERNAL_KEY_STORE",
XksProxyAuthenticationCredential = new Aws.Kms.Inputs.CustomKeyStoreXksProxyAuthenticationCredentialArgs
{
AccessKeyId = ephemeralAccessKeyId,
RawSecretAccessKey = ephemeralSecretAccessKey,
},
XksProxyConnectivity = "PUBLIC_ENDPOINT",
XksProxyUriEndpoint = "https://myproxy.xks.example.com",
XksProxyUriPath = "/kms/xks/v1",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kms.CustomKeyStore;
import com.pulumi.aws.kms.CustomKeyStoreArgs;
import com.pulumi.aws.kms.inputs.CustomKeyStoreXksProxyAuthenticationCredentialArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new CustomKeyStore("example", CustomKeyStoreArgs.builder()
.customKeyStoreName("example-public-xks")
.customKeyStoreType("EXTERNAL_KEY_STORE")
.xksProxyAuthenticationCredential(CustomKeyStoreXksProxyAuthenticationCredentialArgs.builder()
.accessKeyId(ephemeralAccessKeyId)
.rawSecretAccessKey(ephemeralSecretAccessKey)
.build())
.xksProxyConnectivity("PUBLIC_ENDPOINT")
.xksProxyUriEndpoint("https://myproxy.xks.example.com")
.xksProxyUriPath("/kms/xks/v1")
.build());
}
}
resources:
example:
type: aws:kms:CustomKeyStore
properties:
customKeyStoreName: example-public-xks
customKeyStoreType: EXTERNAL_KEY_STORE
xksProxyAuthenticationCredential:
accessKeyId: ${ephemeralAccessKeyId}
rawSecretAccessKey: ${ephemeralSecretAccessKey}
xksProxyConnectivity: PUBLIC_ENDPOINT
xksProxyUriEndpoint: https://myproxy.xks.example.com
xksProxyUriPath: /kms/xks/v1
This configuration mirrors the VPC example but sets xksProxyConnectivity to PUBLIC_ENDPOINT, routing traffic over the public internet instead of through a VPC endpoint service. The xksProxyVpcEndpointServiceName property is omitted since no private connectivity is needed.
Beyond these examples
These snippets focus on specific custom key store features: CloudHSM integration and external key store connectivity (VPC and public). They’re intentionally minimal rather than full key management solutions.
The examples reference pre-existing infrastructure such as CloudHSM clusters with trust anchor certificates, VPC endpoint services for private connectivity, and external XKS proxy endpoints. They focus on configuring the custom key store rather than provisioning the underlying key management infrastructure.
To keep things focused, common custom key store patterns are omitted, including:
- Custom key store lifecycle management (connect/disconnect operations)
- Key creation within custom key stores
- Rotation and backup strategies
- Authentication credential rotation
These omissions are intentional: the goal is to illustrate how each custom key store type is wired, not provide drop-in key management modules. See the KMS Custom Key Store resource reference for all available configuration options.
Let's configure AWS KMS Custom Key Stores
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Key Store Types & Configuration
AWS_CLOUDHSM) uses AWS CloudHSM clusters and requires cloudHsmClusterId, keyStorePassword, and trustAnchorCertificate. External Key Store (EXTERNAL_KEY_STORE) connects to external key management systems and requires xksProxyAuthenticationCredential, xksProxyConnectivity, xksProxyUriEndpoint, and xksProxyUriPath.AWS_CLOUDHSM if customKeyStoreType is omitted.customKeyStoreType to AWS_CLOUDHSM (or omit it for the default), then provide cloudHsmClusterId, keyStorePassword, and trustAnchorCertificate.Immutability & Lifecycle
customKeyStoreType, cloudHsmClusterId, and trustAnchorCertificate. Changing any of these requires replacing the resource.External Key Store Connectivity
xksProxyConnectivity to VPC_ENDPOINT_SERVICE and provide xksProxyVpcEndpointServiceName along with the standard external key store properties (xksProxyAuthenticationCredential, xksProxyUriEndpoint, xksProxyUriPath).xksProxyConnectivity to PUBLIC_ENDPOINT and provide xksProxyAuthenticationCredential, xksProxyUriEndpoint, and xksProxyUriPath. No VPC endpoint service name is needed.VPC_ENDPOINT_SERVICE) routes traffic through a private VPC endpoint service and requires xksProxyVpcEndpointServiceName. Public endpoint connectivity (PUBLIC_ENDPOINT) connects directly over the internet without VPC configuration.