> ## Documentation Index
> Fetch the complete documentation index at: https://docs.futurex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure OpenBao with the Futurex PKCS #11 library

> Configure the OpenBao service to use the Futurex PKCS #11 library for HSM auto-unseal: create the RSA seal key, set the PIN and seal stanza, and initialize OpenBao.

This page configures the OpenBao service that the `openbao-hsm` package installed to use the Futurex PKCS #11 library for HSM auto-unseal. OpenBao seals its root key with an RSA key pair on the Excrypt HSM by using the `CKM_RSA_PKCS_OAEP` mechanism.

The OpenBao configuration on this page is an example to help you get started. Adjust it for your environment, security requirements, and operational preferences, such as TLS and audit logging. Always review and align settings with your organization's security policies.

> [!WARNING]
>
> Use an RSA seal key with this integration. The AES-GCM seal mechanism (`CKM_AES_GCM`) doesn't work with the Futurex PKCS #11 library, because OpenBao and the library handle the GCM initialization vector differently.

## Create the seal key

Create an RSA key pair on the HSM. OpenBao uses the public key to encrypt its root key and the private key to decrypt it at startup. Use the OpenSC `pkcs11-tool`, or the Futurex `PKCS11Manager` program.

**Step 1**

If `pkcs11-tool` isn't installed, install the OpenSC package, for example on Debian or Ubuntu:

```shell title="Shell" theme={null}
sudo apt install opensc
```

**Step 2**

Generate a 2048-bit RSA key pair. Enter the identity password when prompted. Choose any label; you use it again in the OpenBao configuration:

```shell title="Shell" wrap theme={null}
pkcs11-tool --module /usr/local/lib/fxpkcs11/libfxpkcs11.so --login --keypairgen --key-type RSA:2048 --label bao_seal_rsa --usage-decrypt
```

> [!NOTE]
>
> HSM key labels can contain only letters, digits, and underscores.

**Step 3**

Verify that the key pair exists:

```shell title="Shell" wrap theme={null}
pkcs11-tool --module /usr/local/lib/fxpkcs11/libfxpkcs11.so --login --list-objects --type privkey
```

> [!TIP]
>
> The output lists a private key object with the label that you chose.

## Give the openbao user access

The OpenBao service runs as the `openbao` user, which must be able to read the library and its configuration file.

**Step 1**

Verify that the `openbao` user can read `libfxpkcs11.so` and `fxpkcs11.cfg`:

```shell title="Shell" theme={null}
sudo -u openbao ls -la /usr/local/lib/fxpkcs11/libfxpkcs11.so
sudo -u openbao cat /etc/fxpkcs11.cfg
```

> [!TIP]
>
> Each command returns the file details or contents without a permission-denied error.

**Step 2**

If you use mutual authentication, make the TLS client key readable by the `openbao` user, for example:

```shell title="Shell" theme={null}
sudo chown root:openbao /etc/fxpkcs11/tls/PKI.p12
sudo chmod 640 /etc/fxpkcs11/tls/PKI.p12
```

**Step 3**

If `fxpkcs11.cfg` sets a `<LOG-FILE>`, create the file and give it to the `openbao` user. Adjust the path to match your configuration:

```shell title="Shell" theme={null}
sudo touch /var/log/openbao_fxpkcs11.log
sudo chown openbao:openbao /var/log/openbao_fxpkcs11.log
sudo chmod 640 /var/log/openbao_fxpkcs11.log
```

## Set the HSM PIN

OpenBao reads the identity password from the `BAO_HSM_PIN` environment variable. The service loads it from `/etc/openbao/openbao.env`.

**Step 1**

Add the PIN to the environment file. Replace `[identity_password]` with the password of the identity that you created for OpenBao:

```shell title="Shell" theme={null}
echo 'BAO_HSM_PIN=[identity_password]' | sudo tee /etc/openbao/openbao.env > /dev/null
```

If `fxpkcs11.cfg` isn't at `/etc/fxpkcs11.cfg`, also add `FXPKCS11_CFG=[path_to_cfg]` to this file.

**Step 2**

Restrict the file so that only root and the `openbao` group can read it:

```shell title="Shell" theme={null}
sudo chown root:openbao /etc/openbao/openbao.env
sudo chmod 640 /etc/openbao/openbao.env
```

## Configure OpenBao settings

**Step 1**

Replace the contents of `/etc/openbao/openbao.hcl` with the following configuration. Replace `[server_address]` with the address of the OpenBao server and `bao_seal_rsa` with the label of your seal key.

> [!NOTE]
>
> This example disables TLS on the listener for simplicity, so `api_addr` uses HTTP. Before you deploy to production, enable TLS in the `listener` stanza (the package generated a self-signed certificate in `/opt/openbao/tls`) and update `api_addr` to use `https://`. For multi-node Raft deployments, add `node_id` to the `storage` stanza.

```hcl title="/etc/openbao/openbao.hcl" theme={null}
storage "raft" {
  path = "/opt/openbao/data"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = true
}

seal "pkcs11" {
  lib       = "/usr/local/lib/fxpkcs11/libfxpkcs11.so"
  slot      = "0"
  key_label = "bao_seal_rsa"
  mechanism = "CKM_RSA_PKCS_OAEP"
}

api_addr     = "http://[server_address]:8200"
cluster_addr = "http://[server_address]:8201"
ui           = true
```

The `seal` stanza defines the following parameters:

| Parameter | Description |
| - | - |
| **lib** | Path to the Futurex PKCS #11 library. The `openbao` user must be able to read it. |
| **slot** | The slot number. Set it to `0`, the slot that `fxpkcs11.cfg` defines. |
| **key\_label** | The label of the RSA key pair that you created. |
| **mechanism** | Set it to `CKM_RSA_PKCS_OAEP`. |

> [!NOTE]
>
> The configuration file doesn't contain the PIN. OpenBao reads it from the `BAO_HSM_PIN` environment variable.

**Step 2**

Make the configuration file readable by the `openbao` user:

```shell title="Shell" theme={null}
sudo chown openbao:openbao /etc/openbao/openbao.hcl
sudo chmod 640 /etc/openbao/openbao.hcl
```

## Start the OpenBao server

**Step 1**

Delay the OpenBao service at system startup. With the Futurex PKCS #11 library, OpenBao can fail to auto-unseal when it starts in the first minute after the computer boots: it stays sealed and logs `CKR_OBJECT_HANDLE_INVALID`. Starting it later avoids the problem.

Create a systemd drop-in file:

```shell title="Shell" theme={null}
sudo mkdir -p /etc/systemd/system/openbao.service.d
sudo tee /etc/systemd/system/openbao.service.d/10-hsm-start-delay.conf > /dev/null <<'EOF'
[Service]
ExecStartPre=/bin/sh -c 'u=$$(cut -d. -f1 /proc/uptime); [ $$u -ge 90 ] || sleep $$((90 - u))'
TimeoutStartSec=180
EOF
sudo systemctl daemon-reload
```

The drop-in waits until the computer has been up for 90 seconds. It doesn't delay a restart of the service after that.

**Step 2**

Enable and start the OpenBao service:

```shell title="Shell" theme={null}
sudo systemctl enable --now openbao
```

**Step 3**

Check the service status:

```shell title="Shell" theme={null}
sudo systemctl status openbao
```

> [!TIP]
>
> The service is `active (running)`. Until you initialize OpenBao, the log repeats `stored unseal keys are supported, but none were found: is the server initialized?` every few seconds. That's expected.

## Initialize OpenBao

**Step 1**

Set the OpenBao address. Replace `[server_address]` with the address of the OpenBao server:

```shell title="Shell" theme={null}
export BAO_ADDR="http://[server_address]:8200"
```

**Step 2**

Check the OpenBao status:

```shell title="Shell" theme={null}
bao status
```

> [!TIP]
>
> The output shows `Seal Type pkcs11`, `Initialized false`, and `Sealed true`.

**Step 3**

Initialize OpenBao:

```shell title="Shell" theme={null}
bao operator init
```

> [!TIP]
>
> The output lists five recovery keys and an initial root token, and ends with the following lines. OpenBao 2.6 still prints "Vault" in this message:
>
> ```text theme={null}
> Success! Vault is initialized
>
> Recovery key initialized with 5 key shares and a key threshold of 3. Please
> securely distribute the key shares printed above.
> ```

> [!WARNING]
>
> Save the recovery keys and the root token immediately. You can't retrieve them again. Because the HSM unseals OpenBao automatically, you need the recovery keys only for privileged operations, such as generating a new root token. They can't unseal OpenBao if the HSM is unavailable.

**Step 4**

Verify that OpenBao is unsealed:

```shell title="Shell" theme={null}
bao status
```

> [!TIP]
>
> The output shows `Initialized true` and `Sealed false`.

## Troubleshooting

### The service doesn't start or OpenBao stays sealed

Check the service log first:

```shell title="Shell" theme={null}
sudo journalctl -u openbao -b
```

Then use the following table:

| Log message | Cause and fix |
| - | - |
| `CKR_PIN_INCORRECT` | `BAO_HSM_PIN` in `/etc/openbao/openbao.env` doesn't match the identity password. Correct it and restart the service. |
| `CKR_OBJECT_HANDLE_INVALID`, and OpenBao stays sealed after the computer boots | OpenBao started too soon after boot. Check that the start delay drop-in from [Start the OpenBao server](#start-the-openbao-server) exists, then run `sudo systemctl restart openbao`. |
| `Permission denied` when OpenBao loads the library | The `openbao` user can't read `libfxpkcs11.so`, `fxpkcs11.cfg`, or the TLS client key. Check the permissions as described in [Give the openbao user access](#give-the-openbao-user-access). |
| `stored unseal keys are supported, but none were found` | OpenBao isn't initialized yet. Run `bao operator init`. |

For any other library error, enable traffic logging in `fxpkcs11.cfg`, restart the service, and check the log file for `ERROR` lines. See [Edit the Futurex PKCS #11 configuration file](https://docs.futurex.com/Integrations/HSM/Secrets_management/OpenBao/Edit_the_Futurex_PKCS_11_Configuration_File.md).

### The seal key was replaced

If you delete or replace the seal key on the HSM after initialization, OpenBao can no longer decrypt its root key and stays sealed. Restore the original key from an HSM backup. To change the seal key without losing data, follow the key rotation procedure in [Test OpenBao with a Futurex HSM](https://docs.futurex.com/Integrations/HSM/Secrets_management/OpenBao/Testing_OpenBao_with_Futurex_HSM.md).
