Enable Per-Volume Encryption¶
This guide shows you how to enable ZFS native per-volume encryption, backed by OpenBao. Once enabled, volumes provisioned from an encrypted StorageClass are created with their own encryption key, and deleting such a volume crypto-shreds its data.
Before you rely on this, understand what it protects: encryption is at rest on the storage node only. Read Encryption for the security boundary, including the fact that NVMe-TCP and NFS traffic is not encrypted in flight unless you separately enable transport security.
Prerequisites¶
Before you begin, verify that you have the following:
- A reachable OpenBao instance with the Transit secrets engine enabled.
- OpenBao configured for Kubernetes authentication, with a role the driver's ServiceAccount can assume.
- Permission to install or upgrade the zfs-csi Helm release.
Step 1: Prepare OpenBao¶
Enable the Transit engine and create a role bound to the driver's ServiceAccount. The driver
authenticates as the zfs-csi-storage ServiceAccount in the release namespace by default.
The OpenBao role must permit the driver to create and use per-volume keys under the Transit
mount. Configure the Kubernetes auth role to map the zfs-csi-storage and zfs-csi-controller
ServiceAccounts to a policy granting Transit key generation and encryption or decryption.
Note: Use Kubernetes authentication rather than a static token wherever possible. A static token is supported for development only.
Step 2: Enable Encryption in the Helm Values¶
Set the encryption values to point at your OpenBao instance. Save this as
encryption-values.yaml:
encryption:
enabled: true
openbao:
addr: https://openbao.example.com:8200
transitMount: transit
role: zfs-csi-storage
Apply the change. --reuse-values preserves your existing install values while the file
layers the encryption settings on top:
helm upgrade zfs-csi ./charts/zfs-csi \
--namespace zfs-csi-system \
--reuse-values \
--values encryption-values.yaml
Enabling encryption does two things: it configures the controller and storage agent to
authenticate to OpenBao, and it causes the chart to render an additional StorageClass named
zfs-tank-nvme-encrypted.
Note: zfs-tank-nvme-encrypted is the only encrypted StorageClass the chart renders.
There is no encrypted variant of the NFS or flash classes.
Step 3: Provision an Encrypted Volume¶
Create a claim against the encrypted StorageClass:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: secret-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: zfs-tank-nvme-encrypted
resources:
requests:
storage: 10Gi
The driver generates a per-volume key through OpenBao Transit and creates the dataset with
encryption=on.
Step 4: Verify Encryption¶
Confirm the volume's Volume custom resource reports the key as available. The
status.keyStatus field should read Available and the Encrypted condition should be true:
How Deletion Crypto-Shreds Data¶
When you delete an encrypted volume, the driver destroys the ZFS dataset and removes the volume's key from OpenBao. Without the key, the underlying blocks are unrecoverable ciphertext. This per-volume crypto-shred is the reason to build encryption into the driver rather than relying on whole-pool encryption.
Related Practices¶
- Security boundary: Encryption (explanation)
- Values: Helm Values Reference (reference)
- Install: Install zfs-csi with Helm (how-to)