1--- 2layout: "guides" 3page_title: "Seal Wrap / FIPS 140-2 - Guides" 4sidebar_title: "Seal Wrap / FIPS 140-2" 5sidebar_current: "guides-operations-seal-wrap" 6description: |- 7 In this guide, 8--- 9 10 11# Seal Wrap / FIPS 140-2 12 13~> **Enterprise Only:** Vault's HSM auto-unseal and Seal Wrap features are a 14part of _Vault Enterprise_. 15 16***Vault Enterprise*** integrates with [HSM platforms](/docs/enterprise/hsm/index.html) 17to opt-in automatic [unsealing](/docs/concepts/seal.html#unsealing). 18HSM integration provides three pieces of special functionality: 19 20- **Master Key Wrapping**: Vault protects its master key by transiting it through 21the HSM for encryption rather than splitting into key shares 22- **Automatic Unsealing**: Vault stores its encrypted master key in storage, 23allowing for automatic unsealing 24- **Seal Wrapping** to provide FIPS KeyStorage-conforming functionality for Critical Security Parameters 25 26![Unseal with HSM](/img/vault-hsm-autounseal.png) 27 28In some large organizations, there is a fair amount of complexity in designating 29key officers, who might be available to unseal Vault installations as the most 30common pattern is to deploy Vault immutably. As such automating unseal using an 31HSM provides a simplified yet secure way of unsealing Vault nodes as they get 32deployed. 33 34Vault pulls its encrypted master key from storage and transit it through the 35HSM for decryption via **PKCS \#11 API**. Once the master key is decrypted, 36Vault uses the master key to decrypt the encryption key to resume with Vault 37operations. 38 39 40## Reference Material 41 42- [HashiCorp + AWS: Integrating CloudHSM with Vault Enterprise](https://www.hashicorp.com/resources/hashicorp-and-aws-integrating-cloudhsm-with-vault-e) webinar 43- [Seal Wrap documentation](/docs/enterprise/sealwrap/index.html) 44- [Vault Configuration - pkcs11 Seal](/docs/configuration/seal/pkcs11.html) 45- [Vault Enterprise HSM Support](/docs/enterprise/hsm/index.html) 46- [NIST SC-12: Cryptographic Key Establishment and Management](https://nvd.nist.gov/800-53/Rev4/control/SC-12) 47- [NIST SC-13: Cryptographic Protection](https://nvd.nist.gov/800-53/Rev4/control/SC-13) 48 49 50## Estimated Time to Complete 51 5210 minutes 53 54 55## Challenge 56 57The Federal Information Processing Standard (FIPS) 140-2 is a U.S. Government 58computer security standard used to accredit cryptography modules. If your 59product or service does not follow FIPS' security requirements, it may 60complicate your ability to operate with U.S. Government data. 61 62Aside from doing business with U.S. government, your organization may care about 63FIPS which approves various cryptographic ciphers for hashing, signature, key 64exchange, and encryption for security. 65 66 67## Solution 68 69Integrate Vault with FIPS 140-2 certified HSM and enable the ***Seal Wrap*** 70feature to protect your data. 71 72Vault encrypts secrets using 256-bit AES in GCM mode with a randomly generated 73nonce prior to writing them to its persistent storage. By enabling seal wrap, 74Vault wraps your secrets with **an extra layer of encryption** leveraging the 75HSM encryption and decryption. 76 77![Seal Wrap](/img/vault-seal-wrap.png) 78 79#### Benefits of the Seal Wrap: 80 81- Conformance with FIPS 140-2 directives on Key Storage and Key Transport as [certified by Leidos](/docs/enterprise/sealwrap/index.html#fips-140-2-compliance) 82- Supports FIPS level of security equal to HSM 83 * For example, if you use Level 3 hardware encryption on an HSM, Vault will be 84 using FIPS 140-2 Level 3 cryptography 85- Allows Vault to be deployed in high security [GRC](https://en.wikipedia.org/wiki/Governance,_risk_management,_and_compliance) 86environments (e.g. PCI-DSS, HIPAA) where FIPS guidelines important for external audits 87- Pathway for Vault's use in managing Department of Defense's (DOD) or North 88Atlantic Treaty Organization (NATO) military secrets 89 90 91## Prerequisites 92 93This intermediate operations guide assumes that you have: 94 95- A [supported HSM](/docs/enterprise/hsm/index.html) cluster to be integrated 96 with Vault 97- Vault Enterprise Premium 98 99 100 101## Steps 102 103This guide walks you through the following steps: 104 1051. [Configure HSM Auto-unseal](#step1) 1061. [Enable Seal Wrap](#step2) 1071. [Test the Seal Wrap Feature](#step3) 108 109 110 111### <a name="step1"></a>Step 1: Configure HSM Auto-unseal 112 113When a Vault server is started, it normally starts in a sealed state where a 114quorum of existing unseal keys is required to unseal it. By integrating Vault 115with HSM, your Vault server can be automatically unsealed by the trusted HSM key 116provider. 117 118#### Task 1: Write a Vault configuration file 119 120To integrate your Vault Enterprise server with an HSM cluster, the configuration 121file must define the [`PKCS11 seal` stanza](/docs/configuration/seal/pkcs11.html) 122providing necessary connection information. 123 124 125**Example: `config-hsm.hcl`** 126 127```shell 128# Provide your AWS CloudHSM cluster connection information 129seal "pkcs11" { 130 lib = "/opt/cloudhsm/lib/libcloudhsm_pkcs11.so" 131 slot = "1" 132 pin = "vault:Password1" 133 key_label = "hsm_demo" 134 hmac_key_label = "hsm_hmac_demo" 135 generate_key = "true" 136} 137 138# Configure the storage backend for Vault 139storage "file" { 140 path = "/tmp/vault" 141} 142 143# Addresses and ports on which Vault will respond to requests 144listener "tcp" { 145 address = "127.0.0.1:8200" 146 tls_disable = 1 147} 148 149ui = true 150``` 151 152> **NOTE:** For the purpose of this guide, the storage backend is set to the 153local file system (`/tmp/vault`) to make the verification step easy. 154 155The example configuration defines the following in its **`seal`** stanza: 156 157- **`lib`** is set to the path to the PKCS \#11 library on the virtual machine 158 where Vault Enterprise is installed 159- **`slot`** should be set to the slot number to use 160- **`pin`** is the PKCS \#11 PIN for login 161- **`key_label`** defines the label of the key you want to use 162- **`hmac_key_label`** defines the label of the key you want to use for HMACing. 163 (NOTE: HMAC is optional and only used for mechanisms that do not support 164 authenticated data.) 165- **`generate_key`** is set to `true`. If no existing key with the label 166 specified by `key_label` can be found at Vault initialization time, Vault 167 generates a key 168 169~> **IMPORTANT:** Having Vault generate its own key is the easiest way to get up 170and running, but for security, Vault marks the key as **non-exportable**. If 171your HSM key backup strategy requires the key to be exportable, you should 172generate the key yourself. Refer to the [key generation attributes](/docs/configuration/seal/pkcs11.html#vault-key-generation-attributes). 173 174 175 176 177#### Task 2: Initialize your Vault Enterprise server 178 179Start the Vault server with your Vault configuration file. For example, if your 180configuration file is located at `/home/ec2-user/config-hsm.hcl`, the command 181would look like: 182 183```plaintext 184$ vault server -config=/home/ec2-user/config-hsm.hcl 185 186 SDK Version: 2.03 187==> Vault server configuration: 188 189 HSM PKCS#11 Version: 2.40 190 HSM Library: Cavium PKCS#11 Interface 191 HSM Library Version: 1.0 192 HSM Manufacturer ID: Cavium Networks 193 HSM Type: pkcs11 194 Cgo: enabled 195 Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", tls: "disabled") 196 Log Level: info 197 Mlock: supported: true, enabled: false 198 Storage: file 199 Version: Vault v0.10.1+ent.hsm 200 Version Sha: 0e628142d6b6e5cabfdb9680a6d669d38f15574f 201 202==> Vault server started! Log data will stream in below: 203``` 204 205<br> 206 207In another terminal, set the `VAULT_ADDR` environment variable, and [initialize] 208(/intro/getting-started/deploy.html#initializing-the-vault) your Vault server. 209 210**Example:** 211 212```shell 213# Set the VAULT_ADDR environment variable 214$ export VAULT_ADDR="http://127.0.0.1:8200" 215 216# Initialize Vault 217$ vault operator init 218 219Recovery Key 1: 2bU2wOfmyMqYcsEYo4Mo9q4s/KAODgHHjcmZmFOo+XY= 220Initial Root Token: 8d726c6b-98ba-893f-23d5-be3d2fec480e 221 222Success! Vault is initialized 223 224Recovery key initialized with 1 key shares and a key threshold of 1. Please 225securely distribute the key shares printed above. 226``` 227 228There is only a single master key created which is encrypted by the HSM using 229PKCS \#11, and then placed in the storage. When Vault needs to be unsealed, it 230grabs the HSM encrypted master key from the storage, round trips it through the 231HSM to decrypt the master key. 232 233~> **NOTE:** When Vault is initialized while using an HSM, rather than unseal 234keys being returned to the operator, **recovery keys** are returned. These are 235generated from an internal recovery key that is [split via Shamir's Secret 236Sharing](/docs/enterprise/hsm/behavior.html#initialization), similar to Vault's 237treatment of unseal keys when running without an HSM. Some Vault operations such 238as generation of a root token require these recovery keys. 239 240Login to the Vault using the generated root token to verify. 241 242```plaintext 243$ vault login 8d726c6b-98ba-893f-23d5-be3d2fec480e 244``` 245 246#### Task 3: Verification 247 248Stop and restart the Vault server and then verify its status: 249 250```plaintext 251$ vault status 252 253Key Value 254--- ----- 255Recovery Seal Type shamir 256Sealed false 257Total Recovery Shares 1 258Threshold 1 259Version 0.10.1+ent.hsm 260Cluster Name vault-cluster-80556565 261Cluster ID 40316cdd-3d42-ec36-e7b0-6a7a0684568c 262HA Enabled false 263``` 264 265The `Sealed` status is **`false`** which means that the Vault was automatically 266unsealed upon its start. You can proceed with Vault operations. 267 268 269### <a name="step2"></a>Step 2: Enable Seal Wrap 270 271-> **NOTE:** For FIPS 140-2 compliance, seal wrap requires FIPS 272140-2 Certified HSM which is supported by _Vault Enterprise Premium_. 273 274For some values, seal wrapping is **always enabled** including the recovery key, any 275stored key shares, the master key, the keyring, and more. When working with the 276key/value secret engine, you can enable seal wrap to wrap all data. 277 278 279### CLI command 280 281Check the enabled secret engines. 282 283```plaintext 284$ vault secrets list -format=json 285{ 286 ... 287 "secret/": { 288 "type": "kv", 289 "description": "key/value secret storage", 290 "accessor": "kv_75820543", 291 "config": { 292 "default_lease_ttl": 0, 293 "max_lease_ttl": 0, 294 "force_no_cache": false 295 }, 296 "options": { 297 "version": "1" 298 }, 299 "local": false, 300 "seal_wrap": false 301 }, 302 ... 303``` 304 305Notice that the `seal_wrap` parameter is set to **`false`**. 306 307> For the purpose of comparing seal wrapped data against unwrapped data, enable 308additional key/value secret engine at the `secret2/` path. 309 310```shell 311# Pass the '-seal-wrap' flag when you enable the KV workflow 312$ vault secrets enable -path=secret2/ -version=1 -seal-wrap kv 313``` 314 315The above command enabled [key/value version 1](/docs/secrets/kv/kv-v1.html) with 316seal wrap feature enabled. 317 318```plaintext 319$ vault secrets list -format=json 320{ 321 ... 322 "secret2/": { 323 "type": "kv", 324 "description": "", 325 "accessor": "kv_bdd74241", 326 "config": { 327 "default_lease_ttl": 0, 328 "max_lease_ttl": 0, 329 "force_no_cache": false 330 }, 331 "options": { 332 "version": "1" 333 }, 334 "local": false, 335 "seal_wrap": true 336 }, 337 ... 338``` 339 340Notice that the `seal_wrap` parameter is set to **`true`** at `secret2/`. 341 342 343#### API call using cURL 344 345Check the enabled secret engines. 346 347```plaintext 348$ curl --header "X-Vault-Token: ..." \ 349 http://127.0.0.1:8200/v1/sys/mounts | jq 350... 351 "secret/": { 352 "accessor": "kv_f05b8b9c", 353 "config": { 354 "default_lease_ttl": 0, 355 "force_no_cache": false, 356 "max_lease_ttl": 0 357 }, 358 "description": "key/value secret storage", 359 "local": false, 360 "options": { 361 "version": "2" 362 }, 363 "seal_wrap": false, 364 "type": "kv" 365 }, 366... 367``` 368 369Notice that the `seal_wrap` parameter is set to **`false`**. 370 371> For the purpose of comparing seal wrapped data against unwrapped data, enable 372additional key/value secret engine at the `secret2/` path. 373 374```shell 375# Set the seal_wrap parameter to true in the request payload 376$ tee payload.json <<EOF 377{ 378 "type": "kv", 379 "options": { 380 "version": "1" 381 }, 382 "seal_wrap": true 383} 384EOF 385 386# Enable kv secret engine at secret2/ 387$ curl --header "X-Vault-Token: ..." \ 388 --request POST \ 389 --data @payload.json \ 390 http://127.0.0.1:8200/v1/sys/mounts/secret2 391``` 392 393The above command enabled [key/value version 1](/docs/secrets/kv/kv-v1.html) with 394seal wrap feature enabled. 395 396```plaintext 397$ curl --header "X-Vault-Token: ..." \ 398 http://127.0.0.1:8200/v1/sys/mounts | jq 399{ 400... 401 "secret2/": { 402 "accessor": "kv_724c81c9", 403 "config": { 404 "default_lease_ttl": 0, 405 "force_no_cache": false, 406 "max_lease_ttl": 0 407 }, 408 "description": "", 409 "local": false, 410 "options": { 411 "version": "1" 412 }, 413 "seal_wrap": true, 414 "type": "kv" 415 }, 416 ... 417} 418``` 419 420Notice that the `seal_wrap` parameter is set to **`true`** at `secret2/`. 421 422 423#### Web UI 424 425Open a web browser and launch the Vault UI (e.g. `http://127.0.0.1:8200/ui`) and 426then login. 427 428![Enable Secret Engine](/img/vault-seal-wrap-2.png) 429 430> For the purpose of comparing seal wrapped data against unwrapped data, enable 431additional key/value secret engine at the `secret2/` path. 432 433Select **Enable new engine**. 434 435- Enter **`secret2`** in the path field 436- Select **Version 1** for KV version 437- Select the check box for **Seal Wrap** 438 439![Enable Secret Engine](/img/vault-seal-wrap-3.png) 440 441Click **Enable Engine**. 442 443 444### <a name="step3"></a>Step 3: Test the Seal Wrap Feature 445 446In this step, you are going to: 447 4481. Write some test data 4491. [View the encrypted secrets](#view-the-encrypted-secrets) 450 451#### CLI command 452 453Write a secret at `secret/unwrapped`. 454 455```shell 456# Write a key named 'password' with its value 'my-long-password' 457$ vault kv put secret/unwrapped password="my-long-password" 458 459# Read the path to verify 460$ vault kv get secret/unwrapped 461====== Data ====== 462Key Value 463--- ----- 464password my-long-password 465``` 466 467Write the same secret at `secret2/wrapped`. 468 469```shell 470# Write a key named 'password' with its value 'my-long-password' 471$ vault kv put secret2/wrapped password="my-long-password" 472 473# Read the path to verify 474$ vault kv get secret2/wrapped 475====== Data ====== 476Key Value 477--- ----- 478password my-long-password 479``` 480Using a valid token, you can write and read secrets the same way 481regardless of the seal wrap. 482 483 484 485#### API call using cURL 486 487Write a secret at `secret/unwrapped`. 488 489```shell 490# Create a payload 491$ tee payload.json <<EOF 492{ 493 "data": { 494 "password": "my-long-password" 495 } 496} 497EOF 498 499# Write secret at 'secret/unwrapped' 500$ curl --header "X-Vault-Token: ..." \ 501 --request POST \ 502 --data @payload.json \ 503 http://127.0.0.1:8200/v1/secret/unwrapped 504 505# Read the path to verify 506$ curl --header "X-Vault-Token: ..." \ 507 http://127.0.0.1:8200/v1/secret/unwrapped | jq 508{ 509 "request_id": "cef0b061-3860-6a3c-8bba-1fdbf7be7bf1", 510 "lease_id": "", 511 "renewable": false, 512 "lease_duration": 2764800, 513 "data": { 514 "data": { 515 "password": "my-long-password" 516 } 517 }, 518 "wrap_info": null, 519 "warnings": null, 520 "auth": null 521} 522``` 523 524Write the same secret at `secret2/wrapped`. 525 526```shell 527# Write the same secret at 'secret2/wrapped' 528$ curl --header "X-Vault-Token: ..." \ 529 --request POST \ 530 --data @payload.json \ 531 http://127.0.0.1:8200/v1/secret2/wrapped 532 533# Read the path to verify 534$ curl --header "X-Vault-Token: ..." \ 535 http://127.0.0.1:8200/v1/secret2/wrapped | jq 536{ 537 "request_id": "cc9ce831-2ca7-7115-a899-ce33767bdc2c", 538 "lease_id": "", 539 "renewable": false, 540 "lease_duration": 2764800, 541 "data": { 542 "data": { 543 "password": "my-long-password" 544 } 545 }, 546 "wrap_info": null, 547 "warnings": null, 548 "auth": null 549} 550``` 551 552Using a valid token, you can write and read secrets the same way regardless of 553the seal wrap. 554 555#### Web UI 556 557Select **secret** and click **Create secret**. 558 559![Enable Secret Engine](/img/vault-seal-wrap-4.png) 560 561Enter the following: 562 563- PATH FOR THIS SECTE: `unwrapped` 564- key: `password` 565- value: `my-long-password` 566 567![Enable Secret Engine](/img/vault-seal-wrap-5.png) 568 569Click **Save**. 570 571Repeat the same step for **secret2** to write the same secret at the 572`secret2/wrapped` path. 573 574![Enable Secret Engine](/img/vault-seal-wrap-6.png) 575Click **Save**. 576 577 578Using a valid token, you can write and read secrets the same way 579regardless of the seal wrap. 580 581 582#### View the encrypted secrets 583 584Remember that the Vault server was configured to use the local file system 585(`/tmp/vault`) as its storage backend in this example. 586 587```shell 588# Configure the storage backend for Vault 589storage "file" { 590 path = "/tmp/vault" 591} 592``` 593 594SSH into the machine where the Vault server is running, and check the stored 595values in the `/tmp/vault` directory. 596 597```plaintext 598$ cd /tmp/vault/sdk/logical 599``` 600 601Under the `/tmp/vault/sdk/logical` directory, there are two sub-directories. One 602maps to `secret/` and another maps to `secret2/` although you cannot tell by 603the folder names. 604 605 606View the secret at rest. 607 608```shell 609# One of the directory maps to secret/unwrapped 610$ cd 2da357cd-55f2-7eed-c46e-c477b70bed18 611 612# View its content - password value is encrypted 613$ cat _unwrapped 614{"Value":"AAAAAQICk547prhuhMiBXLq2lx8ZkMpSB3p+GKHAwuMhKrZGSeqsFevMS6YoqTVlbvpU9B4zWPZ2HA 615SeNZ3YMw=="} 616 617# Another directory maps to secret2/wrapped 618$ cd ../5bcea44d-28a3-87af-393b-c6d398fe41d8 619 620# View its content - password value is encrypted 621$ cat _wrapped 622{"Value":"ClBAg9oN7zBBaDBZcsilDAyGkL7soPe7vBA5+ADADuyzo8GuHZHb9UFN2nF1h0OpKEgCIkG3JNHcXt 623tZqCi6szcuNBgF3pwhWGwB4FREM3b5CRIQYK7239Q92gRGrcBBeZD6ghogEtSBDmZJBahk7n4lIYF3X4iBqmwZgH 624Vo4lzWur7rzncgASofCIIhENEEGghoc21fZGVtbyINaHNtX2htYWNfZGVtb3M="} 625``` 626 627Secrets are encrypted regardless; however, the seal-wrapped value is 628significantly longer despite the fact that both values are the same, 629`my-long-password`. 630 631 632~> When Vault's Seal Wrap feature is used with a FIPS 140-2 certified HSM, Vault 633will store Critical Security Parameters (CSPs) in a manner that is compliant 634with KeyStorage and KeyTransit requirements. 635 636 637 638## Next steps 639 640This guide used the local file system as the storage backend to keep it simple. 641To learn more about making your Vault cluster highly available, read the [Vault 642HA with Consul](/guides/operations/vault-ha-consul.html) guide. 643