# Data at rest encryption [Data at rest encryption in Percona Server for MongoDB](https://docs.percona.com/percona-server-for-mongodb/latest/data-at-rest-encryption.html) is supported by the Operator since version 1.1.0. !!! note [Data at rest](https://en.wikipedia.org/wiki/Data_at_rest) means inactive data stored as files, database records, etc. Data at rest encryption is turned on by default. The Operator implements it by either using encryption key stored in a Secret, or obtaining encryption key from the HashiCorp Vault key storage. ## Using encryption key Secret 1. The `secrets.encryptionKey` key in the `deploy/cr.yaml` file should specify the name of the encryption key Secret: ```yaml secrets: ... encryptionKey: my-cluster-name-mongodb-encryption-key ``` Encryption key Secret will be created automatically by the Operator if it doesn’t exist. If you would like to create it yourself, take into account that [the key must be a 32 character string encoded in base64](https://docs.mongodb.com/manual/tutorial/configure-encryption/#local-key-management). 2. The `replsets.configuration`, `replsets.nonvoting.configuration`, and `sharding.configsvrReplSet.configuration` keys should include the following two MongoDB encryption-specific options: ```yaml ... configuration: | ... security: enableEncryption: true encryptionCipherMode: "AES256-CBC" ... ``` The `enableEncryption` option should be set to `true` (the default value). The `security.encryptionCipherMode` option should specify a proper cipher mode for decryption: either `AES256-CBC` (the default value) or `AES256-GCM`. Don't forget to apply the modified `cr.yaml` configuration file as usual: ``` {.bash data-prompt="$" } $ kubectl deploy -f deploy/cr.yaml ``` ## Using HashiCorp Vault storage for encryption keys Starting from the version 1.13, the Operator supports using [HashiCorp Vault](https://www.vaultproject.io/) storage for encryption keys - a universal, secure and reliable way to store and distribute secrets without depending on the operating system, platform or cloud provider. !!! warning Vault integration has technical preview status and is not yet recommended for production environments. The Operator will use Vault if the `deploy/cr.yaml` configuration file contains the following items: * a `secrets.vault` key equal to the name of a specially created Secret, * `configuration` keys for mongod and config servers with a number of Vault-specific options. The Operator itself neither installs Vault, nor configures it; both operations should be done manually, as described in the following parts. ### Installing Vault The following steps will deploy Vault on Kubernetes with the [Helm 3 package manager](https://helm.sh/). Other Vault installation methods should also work, so the instruction placed here is not obligatory and is for illustration purposes. Read more about installation in Vault’s [documentation](https://www.vaultproject.io/docs/platform/k8s). 1. Add helm repo and install: ``` {.bash data-prompt="$" } $ helm repo add hashicorp https://helm.releases.hashicorp.com "hashicorp" has been added to your repositories $ helm install vault hashicorp/vault ``` 2. After installation, Vault should be first initialized and then *unsealed*. Initializing Vault is done with the following commands: ``` {.bash data-prompt="$" } $ kubectl exec -it pod/vault-0 -- vault operator init -key-shares=1 -key-threshold=1 -format=json > /tmp/vault-init $ unsealKey=$(jq -r ".unseal_keys_b64[]" < /tmp/vault-init) ``` To unseal Vault, execute the following command **for each Pod** of Vault running: ``` {.bash data-prompt="$" } $ kubectl exec -it pod/vault-0 -- vault operator unseal "$unsealKey" ``` ### Configuring Vault 1. First, you should enable secrets within Vault. For this you will need a [Vault token](https://www.vaultproject.io/docs/concepts/tokens). Percona Server for MongoDB can use any regular token which allows all operations inside the secrets mount point. In the following example we are using the *root token* to be sure the permissions requirement is met, but actually there is no need in root permissions. We don’t recommend using the root token on the production system. ``` {.bash data-prompt="$" } $ cat /tmp/vault-init | jq -r ".root_token" ``` The output will show you the token: ``` {.text .no-copy} s.VgQvaXl8xGFO1RUxAPbPbsfN ``` Now login to Vault with this token to enable the key-value secret engine: ``` {.bash data-prompt="$" } $ kubectl exec -it vault-0 -- /bin/sh $ vault login s.VgQvaXl8xGFO1RUxAPbPbsfN ``` ??? example "Expected output" ``` {.text .no-copy} Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token. Key Value --- ----- token s.VgQvaXl8xGFO1RUxAPbPbsfN token_accessor iMGp477aReYkPBWrR42Z3L6R token_duration ∞ token_renewable false token_policies ["root"] identity_policies [] policies ["root"]` ``` Now enable the key-value secret engine with the following command: ``` {.bash data-prompt="$" } $ vault secrets enable -path secret kv-v2 ``` ??? example "Expected output" ``` {.text .no-copy} Success! Enabled the kv-v2 secrets engine at: secret/ ``` !!! note You can also enable audit, which is not mandatory, but useful: ``` {.bash data-prompt="$" } $ vault audit enable file file_path=/vault/vault-audit.log ``` ??? example "Expected output" ``` {.text .no-copy} Success! Enabled the file audit device at: file/ ``` 2. Now generate Secret with the Vault root token using `kubectl command` (don't forget to substitute the token from the example with your real root token) and add necessary options to `configuration` keys in your `deploy/cr.yaml`: === "without TLS, to access the Vault server via HTTP" Generate Secret: ``` {.bash data-prompt="$" } $ kubectl create secret generic vault-secret --from-literal=token="s.VgQvaXl8xGFO1RUxAPbPbsfN" ``` Now modify your `deploy/cr.yaml`: First set the `secrets.encryptionKey` key to the name of your Secret created on the previous step. Then Add Vault-specific options to the `replsets.configuration`, `replsets.nonvoting.configuration`, and `sharding.configsvrReplSet.configuration` keys, using the following template: ```yaml ... configuration: | ... security: enableEncryption: true vault: serverName: vault port: 8200 tokenFile: /etc/mongodb-vault/token secret: secret/data/dc// disableTLSForTesting: true ... ``` === "with TLS, to access the Vault server via HTTPS" Generate Secret, using the path to your `ca.crt` certificate instead of the `` placeholder (see [the Operator TLS guide](TLS.md), if needed): ``` {.bash data-prompt="$" } kubectl create secret generic vault-secret --from-literal=token="s.VgQvaXl8xGFO1RUxAPbPbsfN" --from-file=ca.crt=/ca.crt ``` Now modify your `deploy/cr.yaml`: First set the `secrets.encryptionKey` key to the name of your Secret created on the previous step. Then Add Vault-specific options to the `replsets.configuration`, `replsets.nonvoting.configuration`, and `sharding.configsvrReplSet.configuration` keys, using the following template: ```yaml ... configuration: | ... security: enableEncryption: true vault: serverName: vault port: 8200 tokenFile: /etc/mongodb-vault/token secret: secret/data/dc// serverCAFile: /etc/mongodb-vault/ca.crt ... ``` While adding options, modify this template as follows: * substitute the `` placeholder with your real cluster name, * substitute the placeholder with `rs0` when adding options to `replsets.configuration` and `replsets.nonvoting.configuration`, * substitute the placeholder with `cfg` when adding options to `sharding.configsvrReplSet.configuration`. Finally, apply your modified `cr.yaml` as usual: ``` {.bash data-prompt="$" } $ kubectl deploy -f deploy/cr.yaml ``` 3. To verify that everything was configured properly, use the following log filtering command (substitute the `` and `` placeholders with your real cluster name and namespace): ``` {.bash data-prompt="$" } $ kubectl logs -rs0-0 -c mongod -n | grep -i "Encryption keys DB is initialized successfully" ``` More details on how to install and configure Vault can be found [in the official documentation](https://learn.hashicorp.com/vault?track=getting-started-k8s#getting-started-k8s).