﻿---
path: administration/advanced-settings/database-re-encryption.mdx
title: Encryption key rotation
slug: database-re-encryption
pagination_next: null
pagination_prev: null
sidebar_position: 6
description: >-
  Instructions for rotating the Passwork encryption key: preparation, dry run,
  and applying changes.
keywords:
  - Passwork
  - encryption_key
  - re-encryption
  - database
  - MongoDB
  - service mode
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

During encryption key rotation, the database must be re-encrypted. While this operation is running, Passwork is switched to service mode: the web interface and automations become unavailable.

:::danger
Before rotation, you must create a backup copy of the Passwork database and the `encryption_key`.

[**Backup creation and restoration examples**](../../databases/mongodb/backup-creation-and-restoration-examples.mdx)
:::

## General information

During rotation, Passwork reads the current key from `encryption_key` or from the `ENCRYPTION_KEY` environment variable, checks that it matches the internal settings, and reads the new key from the `new_encryption_key` file.

After rotation is completed successfully, `new_encryption_key` replaces the current `encryption_key`. The old key is saved in the same directory with a timestamp.

## Procedure

### Enabling service mode

When service mode is enabled, access to the web interface and automations that use the API is closed. Enabling service mode is required:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="DEB" label="DEB">

```shell
sudo -u www-data bash -c 'cd /var/www && php bin/console app:service-mode enable'
```
  </TabItem>
  <TabItem className="tab-item-container" value="RPM" label="RPM">

```shell
sudo -u apache bash -c 'cd /var/www && php bin/console app:service-mode enable'
```
  </TabItem>
  <TabItem className="tab-item-container" value="Docker" label="Docker">

```shell
docker compose exec -T php-fpm sh -c 'cd /server/www && php bin/console app:service-mode enable'
```
  </TabItem>
  <TabItem className="tab-item-container" value="PowerShell" label="PowerShell">

```powershell
cd "C:\inetpub\wwwroot\passwork"
php .\bin\console app:service-mode enable
```
  </TabItem>
</Tabs>

### Generating a new encryption key

To create a new encryption key and save it to the `new_encryption_key` file:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="DEB" label="DEB">

```shell
sudo -u www-data bash -c 'cd /var/www && php bin/console encryption-key:generate'
```
  </TabItem>
  <TabItem className="tab-item-container" value="RPM" label="RPM">

```shell
sudo -u apache bash -c 'cd /var/www && php bin/console encryption-key:generate'
```
  </TabItem>
  <TabItem className="tab-item-container" value="Docker" label="Docker">

```shell
docker compose exec -T php-fpm sh -c 'cd /server/www && php bin/console encryption-key:generate'
```
  </TabItem>
  <TabItem className="tab-item-container" value="PowerShell" label="PowerShell">

```powershell
php .\bin\console encryption-key:generate
```
  </TabItem>
</Tabs>

:::info
If the **new_encryption_key** file already exists, the command will fail.
:::

### Dry run

The `encryption-key:update` command without the `--apply` parameter runs in **dry-run** mode:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="DEB" label="DEB">

```shell
sudo -u www-data bash -c 'cd /var/www && php -d memory_limit=-1 bin/console encryption-key:update --ansi'
```
  </TabItem>
  <TabItem className="tab-item-container" value="RPM" label="RPM">

```shell
sudo -u apache bash -c 'cd /var/www && php -d memory_limit=-1 bin/console encryption-key:update --ansi'
```
  </TabItem>
  <TabItem className="tab-item-container" value="Docker" label="Docker">

```shell
docker compose exec -T php-fpm sh -c 'cd /server/www && php -d memory_limit=-1 bin/console encryption-key:update --ansi'
```
  </TabItem>
  <TabItem className="tab-item-container" value="PowerShell" label="PowerShell">

```powershell
php -d "memory_limit=-1" .\bin\console encryption-key:update --ansi
```
  </TabItem>
</Tabs>

<details>
  <summary>Output explanation</summary>

| Column | Description |
|--------|-------------|
| `Found` | Number of records or values found that are suitable for checking at this stage. A value of `0` means there is no such data in the database. |
| `Processed` | Number of values that the command successfully checked: decrypted with the old key and prepared for encryption with the new key. |
| `Skipped` | Number of found records that do not require processing or do not contain values for re-encryption. For example, SMTP settings may be found, but the password may be absent. |
| `Restored` | Number of values skipped during a repeated run after interruption because their state already differs from the saved intermediate state. In a normal dry run, this is `0`. |
| `Conflicts` | Number of conflicts while continuing an interrupted operation. For example, if a record saved earlier for continuation can no longer be found. In a normal dry run, this is `0`. |
| `Seconds` | Execution time of a specific stage in seconds. |

</details>

:::danger
If the **dry-run** finishes with an error, re-encryption is not possible until the causes of the errors are resolved.
:::

### Applying re-encryption

The `--apply` parameter starts data modification. Before applying changes, the command displays a warning and asks for confirmation:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="DEB" label="DEB">

```shell
sudo -u www-data bash -c 'cd /var/www && php -d memory_limit=-1 bin/console encryption-key:update --apply'
```
  </TabItem>
  <TabItem className="tab-item-container" value="RPM" label="RPM">

```shell
sudo -u apache bash -c 'cd /var/www && php -d memory_limit=-1 bin/console encryption-key:update --apply'
```
  </TabItem>
  <TabItem className="tab-item-container" value="Docker" label="Docker">

```shell
docker compose exec -T php-fpm sh -c 'cd /server/www && php -d memory_limit=-1 bin/console encryption-key:update --apply'
```
  </TabItem>
  <TabItem className="tab-item-container" value="PowerShell" label="PowerShell">

```powershell
php -d "memory_limit=-1" .\bin\console encryption-key:update --apply
```
  </TabItem>
</Tabs>

After successful completion:

- Encrypted values in the database will be re-encrypted with the new key;
- The `new_encryption_key` file will be renamed to `encryption_key`;
- The old `encryption_key` will be renamed to the backup file `encryption_key.<date_and_time>.bak`.

### Disabling service mode

After re-encryption is completed successfully, service mode must be disabled to restore access to the Passwork web interface and automations:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="DEB" label="DEB">

```shell
sudo -u www-data bash -c 'cd /var/www && php bin/console app:service-mode disable'
```
  </TabItem>
  <TabItem className="tab-item-container" value="RPM" label="RPM">

```shell
sudo -u apache bash -c 'cd /var/www && php bin/console app:service-mode disable'
```
  </TabItem>
  <TabItem className="tab-item-container" value="Docker" label="Docker">

```shell
docker compose exec -T php-fpm sh -c 'cd /server/www && php bin/console app:service-mode disable'
```
  </TabItem>
  <TabItem className="tab-item-container" value="PowerShell" label="PowerShell">

```powershell
php .\bin\console app:service-mode disable
```
  </TabItem>
</Tabs>

:::danger
Service mode should not be disabled before **encryption-key:update --apply** completes successfully.
:::

## If execution was interrupted

If command execution was interrupted, re-encryption can be started again. Passwork saves the operation state and continues processing from the point where the previous attempt stopped.

To continue, use the same `new_encryption_key` file:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="DEB" label="DEB">

```shell
sudo -u www-data bash -c 'cd /var/www && php -d memory_limit=-1 bin/console encryption-key:update --apply'
```
  </TabItem>
  <TabItem className="tab-item-container" value="RPM" label="RPM">

```shell
sudo -u apache bash -c 'cd /var/www && php -d memory_limit=-1 bin/console encryption-key:update --apply'
```
  </TabItem>
  <TabItem className="tab-item-container" value="Docker" label="Docker">

```shell
docker compose exec -T php-fpm sh -c 'cd /server/www && php -d memory_limit=-1 bin/console encryption-key:update --apply'
```
  </TabItem>
  <TabItem className="tab-item-container" value="PowerShell" label="PowerShell">

```powershell
php -d "memory_limit=-1" .\bin\console encryption-key:update --apply
```
  </TabItem>
</Tabs>

:::info
If an error occurs after the **encryption_key** file has been replaced, Passwork will try to restore the old key file from the backup file.
:::

## Checks and limitations

The `encryption-key:update` command will not start if:

- Service mode is disabled;
- The current encryption key does not match the hash in the database;
- The `new_encryption_key` file is missing or damaged.

After successful rotation, check that Passwork works correctly and make sure users can open data. Delete the old key backup only after verifying functionality and confirming that the backup copy is correct.
