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.
What to back up
Section titled “What to back up”| What | Where (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 |
| PostgreSQL | your 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.
Rotate the encryption key
Section titled “Rotate the encryption key”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.
NEW=$(openssl rand -hex 32)
sudo systemctl stop tessera-controller # 1. stop itpg_dump ... > before-rotation.sql # 2. back the database upsudo -E tessera-controller reencrypt -new "$NEW" # 3. rotate# 4. put $NEW in TESSERA_ENC_KEY (/etc/tessera/tessera.secret), then start the controllerThe 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.
Never run a down migration
Section titled “Never run a down migration”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.
Upgrading
Section titled “Upgrading”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.
VM (apt)
Section titled “VM (apt)”The package is deliberately excluded from unattended-upgrades — it never restarts behind your back:
sudo apt update && sudo apt install --only-upgrade tessera-controllertessera.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.
Docker Compose / Kubernetes
Section titled “Docker Compose / Kubernetes”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.
How long a version is supported
Section titled “How long a version is supported”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.
Restoring
Section titled “Restoring”- Restore PostgreSQL from your dump.
- Put
tessera.secret(or the key env vars) and/var/lib/tesseraback in place — the same keys that encrypted the data, and the same SSH host key clients have pinned. - 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.
We would like to count visits with Google Analytics, which needs a cookie. Nothing is loaded and nothing is stored unless you accept. What this sets.