diff --git a/website/content/api-docs/secret/transform.mdx b/website/content/api-docs/secret/transform.mdx index fd356e501b..1fed8d3cbd 100644 --- a/website/content/api-docs/secret/transform.mdx +++ b/website/content/api-docs/secret/transform.mdx @@ -325,7 +325,7 @@ transformation exists, it will be updated with the new attributes. for all plaintexts to be decoded via the export-decoded endpoint in an emergency. -- `max_ttl`: `(duration: "0") +- `max_ttl`: `(duration: "0")` - The maximum TTL of a token. If 0 or unspecified, tokens may have no expiration. - `allowed_roles` `(list: [])` - @@ -356,6 +356,211 @@ $ curl \ https://127.0.0.1:8200/v1/transform/transformations/tokenization/example-transformation ``` +## Import Key for FPE Transformation + +This endpoint imports an existing AES-256 key into a new FPE transformation. +Currently, importing a key into an existing FPE transformation is not supported. + +| Method | Path | +| :----- | :-------------------------------------------- | +| `POST` | `/transform/transformations/fpe/:name/import` | + +### Parameters + +- `name` `(string: )` – Specifies the name of the encryption key to + create. This is specified as part of the URL. + +- `ciphertext` `(string: )` - A base64-encoded string that contains +two values: an ephemeral 256-bit AES key wrapped using the wrapping key +returned by Vault and the encryption of the import key material under the +provided AES key. The wrapped AES key should be the first 512 bytes of the +ciphertext, and the encrypted key material should be the remaining bytes. + +- `hash_function` `(string: "SHA256")` - The hash function used for the +RSA-OAEP step of creating the ciphertext. Supported hash functions are: +`SHA1`, `SHA224`, `SHA256`, `SHA384`, and `SHA512`. If not specified, +the hash function defaults to SHA256. + +- `template` `(string: )` - + Specifies the template name to use for matching value on encode and decode + operations when using this transformation. + +- `tweak_source` `(string: "supplied")` - + Specifies the source of where the tweak value originated. Valid sources are + `supplied`, `generated`, and `internal`. Only used when the type is FPE. + +- `allowed_roles` `(list: [])` - + Specifies a list of allowed roles that this transformation can be assigned to. + A role using this transformation must exist in this list for the + encode and decode operations to function properly. + +### Sample Payload + +```json +{ + "ciphertext": "...", + "template": "builtin/creditcardnumber", + "tweak_source": "internal", + "allowed_roles": ["example-role"] +} +``` + +### Sample Request + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + https://127.0.0.1:8200/v1/transform/transformations/fpe/example-transformation/import +``` + +## Import Key for Tokenization Transformation + +This endpoint imports an existing AES-256 key into a new tokenization transformation. +To import key material into an existing key, see the tokenization `import_version/` endpoint. + +~> **Note:** At this time, tokenization transformations with imported keys do not support +convergent tokenization. + +| Method | Path | +| :----- | :----------------------------------------------------- | +| `POST` | `/transform/transformations/tokenization/:name/import` | + +### Parameters + +- `name` `(string: )` – Specifies the name of the encryption key to + create. This is specified as part of the URL. + +- `ciphertext` `(string: )` - A base64-encoded string that contains +two values: an ephemeral 256-bit AES key wrapped using the wrapping key +returned by Vault and the encryption of the import key material under the +provided AES key. The wrapped AES key should be the first 512 bytes of the +ciphertext, and the encrypted key material should be the remaining bytes. + +- `hash_function` `(string: "SHA256")` - The hash function used for the +RSA-OAEP step of creating the ciphertext. Supported hash functions are: +`SHA1`, `SHA224`, `SHA256`, `SHA384`, and `SHA512`. If not specified, +the hash function defaults to SHA256. + +- `allow_rotation` `(bool: false)` - If set, the imported key can be rotated +within Vault by using the `rotate` endpoint. + +~> **NOTE**: Once an imported key is rotated within Vault, it will no longer +support importing key material with the `import_version` endpoint. + +- `mapping_mode` `(string: "default")` - + Specifies the mapping mode for stored tokenization values. `default` + is strongly recommended for highest security. `exportable` allows + for all plaintexts to be decoded via the export-decoded endpoint + in an emergency. + +- `max_ttl`: `(duration: "0")` - + The maximum TTL of a token. If 0 or unspecified, tokens may have no expiration. + +- `allowed_roles` `(list: [])` - + Specifies a list of allowed roles that this transformation can be assigned to. + A role using this transformation must exist in this list in order for + encode and decode operations to properly function. + +- `stores` `(list: ["builtin/internal"])` - + The list of tokenization stores to use for tokenization state. Vault's + internal storage is used by default. + +### Sample Payload + +```json +{ + "ciphertext": "...", + "max_ttl": "365d", + "allowed_roles": ["example-role"] +} +``` + +### Sample Request + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + https://127.0.0.1:8200/v1/transform/transformations/tokenization/example-transformation/import +``` + +## Import Key Version for Tokenization Transformation + +This endpoint imports new key material into an existing tokenization transformation with an imported key. + +| Method | Path | +| :----- | :------------------------------------------------------------- | +| `POST` | `/transform/transformations/tokenization/:name/import_version` | + +~> **Note**: Transformations whose key material was generated by Vault do not support +importing key material. Only transformations that were created through the `import` +endpoint can import new key material from an external source. + +### Parameters + +- `name` `(string: )` – Specifies the name of the transformation to + create. This is specified as part of the URL. + +- `ciphertext` `(string: )` - A base64-encoded string that contains +two values: an ephemeral 256-bit AES key wrapped using the wrapping key +returned by Vault and the encryption of the import key material under the +provided AES key. The wrapped AES key should be the first 512 bytes of the +ciphertext, and the encrypted key material should be the remaining bytes. + +- `hash_function` `(string: "SHA256")` - The hash function used for the +RSA-OAEP step of creating the ciphertext. Supported hash functions are: +`SHA1`, `SHA224`, `SHA256`, `SHA384`, and `SHA512`. If not specified, +the hash function defaults to SHA256. + +### Sample Payload + +```json +{ + "ciphertext": "...", +} +``` + +### Sample Request + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + https://127.0.0.1:8200/v1/transform/transformations/tokenization/example-transformation/import_version +``` + +## Get Wrapping Key + +This endpoint is used to retrieve the wrapping key to use to import keys. +The returned key will be a 4096-bit RSA public key. + +| Method | Path | +| :---- | :------------------------ | +| `GET` | `/transform/wrapping_key` | + +### Sample Request + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request GET \ + http://127.0.0.1:8200/v1/transform/wrapping_key +``` + +### Sample Response + +```json +{ + "data": { + "public_key": "..." + }, +} +``` + ## Read Transformation This endpoint queries an existing transformation by the given name. diff --git a/website/content/docs/secrets/transform/index.mdx b/website/content/docs/secrets/transform/index.mdx index cb9f6e6905..ba7c2d1d80 100644 --- a/website/content/docs/secrets/transform/index.mdx +++ b/website/content/docs/secrets/transform/index.mdx @@ -282,9 +282,12 @@ possible, as it is resistant to more types of attack. #### Convergent Tokenization +~> **Note:** Convergent tokenization is not supported for transformations with +imported keys. + In addition, tokenization transformations may be configured as *convergent*, meaning that tokenizing a plaintext and expiration more than once results in the -same token value. Enabling convergence has performance and security +same token value. Enabling convergence has performance and security [considerations](transform/tokenization#convergence). ## Deletion Behavior @@ -352,6 +355,61 @@ transformations: Refer to the [Transform Secrets Engine](https://learn.hashicorp.com/vault/adp/transform) tutorial to learn how to use the Transform secrets engine to handle secure data transmission and tokenization against provided secrets. +## Bring Your Own Key (BYOK) + +~> **Note:** Key import functionality supports cases where there is a need to bring +in an existing key from an HSM or other outside systems. It is more secure to +have Transform generate and manage a key within Vault. + +First, the wrapping key needs to be read from the transform secrets engine: + +```text +$ vault read transform/wrapping_key +``` + +The wrapping key will be a 4096-bit RSA public key. + +Then, the wrapping key is used to create the ciphertext input for the `import` endpoint, +as described below. The target key refers to the key being imported. + +### HSM + +If the key is being imported from an HSM that supports PKCS#11, there are +two possible scenarios: + +- If the HSM supports the CKM_RSA_AES_KEY_WRAP mechanism, it can be used to wrap the +target key using the wrapping key. + +- Otherwise, two mechanisms can be combined to wrap the target key. First, a 256-bit AES key is +generated and then used to wrap the target key using the CKM_AES_KEY_WRAP_KWP mechanism. +Then the AES key should be wrapped under the wrapping key using the CKM_RSA_PKCS_OAEP mechanism +using MGF1 and either SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512. + +The ciphertext is constructed by appending the wrapped target key to the wrapped AES key. + +The ciphertext bytes should be base64-encoded. + +### Manual Process + +If the target key is not stored in an HSM or KMS, the following steps can be used to construct +the ciphertext for the input of the `import` endpoint: + +1. Generate an ephemeral 256-bit AES key. + +2. Wrap the target key using the ephemeral AES key with AES-KWP. + +3. Wrap the AES key under the Vault wrapping key using RSAES-OAEP with MGF1 and +either SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512. + +4. Delete the ephemeral AES key. + +5. Append the wrapped target key to the wrapped AES key. + +6. Base64 encode the result. + +For more details on the key wrapping process, see the [key wrapping guide](/docs/transit/key-wrapping-guide) +(be sure to use the transform wrapping key when wrapping a key for import into the transform secrets engine). + ## API The Transform secrets engine has a full HTTP API. Please see the