AWS KMS External Key Store can use Vault as a key store via the Vault PKCS#11 Provider.
---
# Vault with AWS KMS External Key Store (XKS) via PKCS#11 and XKS Proxy
~> **Note**: AWS [`xks-proxy`](https://github.com/aws-samples/aws-kms-xks-proxy) is used in this document as a sample implementation.
Vault's KMIP Secrets Engine can be used as an external key store for the AWS KMS [External Key Store (XKS)](https://aws.amazon.com/blogs/aws/announcing-aws-kms-external-key-store-xks/) protocol using the AWS [`xks-proxy`](https://github.com/aws-samples/aws-kms-xks-proxy) along
with the [Vault PKCS#11 Provider](https://developer.hashicorp.com/vault/docs/enterprise/pkcs11-provider).
## Overview
This is tested as working with Vault 1.11.0 Enterprise (and later) with Advanced Data Protection (KMIP support).
* `libvault-pkcs11.so` downloaded from [releases.hashicorp.com](https://releases.hashicorp.com/vault-pkcs11-provider) for your platform and available on the XKS Proxy server.
* Vault Enterprise with the KMIP Secrets Engine available and with TCP port 5696 accessible to where XKS Proxy will be running.
There are 3 parts to this setup:
1. Vault KMIP Secrets Engine standard setup. (There is nothing specific to XKS in this setup.)
1. Vault PKCS#11 setup to tell the PKCS#11 provider (`libvault-pkcs11.so`) how to talk to the Vault KMIP Secrets Engine. (There is nothing specific to XKS in this setup.)
For this example, We will use an HTTPS proxy service like [ngrok](https://ngrok.com/) to forward connections
to the XKS proxy. This helps to quickly setup a valid domain and TLS endpoint for testing.
1. Start `ngrok`:
```shell-session
$ ngrok http 8000
```
This will output a domain that can be used to configure KMS later, such as `https://example.ngrok.io`.
1. Copy the `libvault-pkcs11.so` binary to the server, such as `/usr/local/lib` (should be same as in the TOML config file below), and `chmod` it so that it is executable.
1. Copy the TLS certificate bundle (e.g., `/etc/kmip/cert.pem`) and CA bundle (e.g., `/etc/kmip/ca.pem`) to the `xks-proxy` server (doesn't matter where, as long as the `xks-proxy` process has access to it) from the Vault setup.
1. Create a `configuration/settings_vault.toml` file for the XKS to Vault PKCS#11 configuration,
and set the `XKS_PROXY_SETTINGS_TOML` environment variable to point to the file location.
The important settings to change:
* `[tls]`: change key and certificate location to point to KMIP certs
* `[[external_key_stores]]`:
* change URI path prefix to anything you like
* choose random access ID
* choose random secret key
* set which key labels are accessible to XKS (`xks_key_id_set`)
* `[pkcs11]`: set the `PKCS11_HSM_MODULE` to the location of the `libvault-pkcs11.so` (or `.dylib`) file downloaded from [releases.hashicorp.com](https://releases.hashicorp.com/vault-pkcs11-provider).
1. Create a file, `/etc/vault-pkcs11.hcl` with the following contents:
```hcl
slot {
server = "VAULT_ADDRESS:5696"
tls_cert_path = "/etc/kmip/cert.pem"
ca_path = "/etc/kmip/ca.pem"
scope = "my-service"
}
```
This file is used by `libvault-pkcs11.so` to know how to find and communicate with the KMIP server.
See [the Vault docs](https://developer.hashicorp.com/vault/docs/enterprise/pkcs11-provider) for all available parameters and their usage.
1. If you want to view the Vault logs (helpful when trying to find error messages), you can specify the `VAULT_LOG_FILE` (default is stdout) and `VAULT_LOG_LEVEL` (default is `INFO`). We'd recommend setting `VAULT_LOG_FILE` to something like `/tmp/vault.log` or `/var/log/vault.log`. Other useful log levels are `WARN` (quieter) and `TRACE` (very verbose, could possibly contain sensitive information, like raw network packets).
1. Create an AES-256 key in KMIP, for example, using `pkcs11-tool` (usually installed with the OpenSC package). See the [Vault docs](https://developer.hashicorp.com/vault/docs/enterprise/pkcs11-provider) for the full setup.
```sh
VAULT_LOG_FILE=/dev/null pkcs11-tool --module ./libvault-pkcs11.so --keygen -a abc123 --key-type AES:32 \
--extractable --allow-sw
Key generated:
Secret Key Object; AES length 32
VALUE:
label: abc123
Usage: encrypt, decrypt, wrap, unwrap
Access: none
```
## Enable XKS in the AWS CLI
1. Create the KMS custom key store with the appropriate parameters to point to your XKS proxy (in this example, through `ngrok`).