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