Skip to content

Backups & upgrades

The controller is deliberately simple to operate: one binary, one database, one data directory. But two things are irreplaceable — the encryption key and the SSH proxy host key — so read this page before going to production.

WhatWhere (VM install)Why
Encryption keys/etc/tessera/tessera.secret (containers: the TESSERA_ENC_KEY / TESSERA_JWT_SECRET values)TESSERA_ENC_KEY encrypts every stored credential — losing it makes them all permanently unrecoverable. It can be rotated
Audit signing key/etc/tessera/tessera.secret → TESSERA_AUDIT_SIGN_KEY (containers: the same variable)signs every sealed audit block. Losing it harms no data, but every signature made with it stops verifying, so the tamper evidence for that history is gone. Generated for you on a VM install; on containers, set it
PostgreSQLyour database server (pg_dump)targets, encrypted credentials, users, grants, the audit log
Data directory/var/lib/tessera (containers: the data volume)session recordings and the SSH proxy host key
Config/etc/tessera/tessera.conf (containers: your compose/values files)quick to recreate, but back it up anyway

Store the tessera.secret backup somewhere safe and separate from the database backup — together they decrypt every credential.

TESSERA_ENC_KEY can be replaced. Losing it is still unrecoverable, but a key that has been exposed — a leaked backup of tessera.secret, an operator who left, a policy that says keys are replaced yearly — no longer means the installation is stuck with it.

Terminal window
NEW=$(openssl rand -hex 32)
sudo systemctl stop tessera-controller # 1. stop it
pg_dump ... > before-rotation.sql # 2. back the database up
sudo -E tessera-controller reencrypt -new "$NEW" # 3. rotate
# 4. put $NEW in TESSERA_ENC_KEY (/etc/tessera/tessera.secret), then start the controller

The command reads the current key from TESSERA_ENC_KEY, exactly where the controller reads it, so it cannot be aimed at the wrong database by accident: a key that does not match the data fails on the first secret and writes nothing.

Everything happens in one transaction, and every secret is decrypted with the new key and compared before the commit. There is no half-rotated state to recover from: either every credential opens with the new key or nothing changed. The controller must be stopped, because one running alongside would write new credentials under the old key while the rotation is in flight.

The controller applies migrations forward, at startup, and nothing in the product ever rolls one back. Driving goose down against the database by hand is not a supported operation, and one migration in particular (0037, which corrected a chain that had sealed history it could not vouch for) will redo its work if it is ever re-applied: it unseals the live chain and removes every block header, restarting sequence numbers your SIEM has already recorded. Restore from a backup instead.

An upgrade restarts the controller, and sessions live in memory — so active SSH/RDP sessions drop. Upgrades are therefore a planned action: pick a maintenance window and tell your users. Database and Kubernetes tunnels are re-established by the desktop app on relaunch; SSH and RDP sessions are not.

The package is deliberately excluded from unattended-upgrades — it never restarts behind your back:

Terminal window
sudo apt update && sudo apt install --only-upgrade tessera-controller

tessera.conf, tessera.secret and /var/lib/tessera are preserved. The latest config template is written next to yours as /etc/tessera/tessera.conf.example for comparison, and the database schema migrates automatically on start.

Bump the image tag (Compose) or chart version (Helm) and redeploy — the exact commands are in Docker Compose and Kubernetes. The controller is a single replica by design, so the rollout is a restart, not a rolling update.

Every published version receives security updates for at least five years from its release date, on every edition including Community. This is the support period declared under the EU Cyber Resilience Act and it is written into the licence, so it does not depend on holding a subscription.

Fixes land in the current minor release and the one before it. Staying further back than that is supported in the sense that the version is still in its five-year window, but collecting a fix will mean upgrading to a release that carries it. Vulnerabilities are handled under the disclosure policy.

  1. Restore PostgreSQL from your dump.
  2. Put tessera.secret (or the key env vars) and /var/lib/tessera back in place — the same keys that encrypted the data, and the same SSH host key clients have pinned.
  3. Install the same (or newer) controller version and start it. Migrations are applied automatically and are safe to re-run.

If the encryption key you restore doesn’t match the database, the controller starts but stored credentials fail to decrypt — see Troubleshooting.