-
-
Notifications
You must be signed in to change notification settings - Fork 43
Backup Restore and Secret Rotation
WebSSH provides native administrator and CLI workflows for backing up persistent state, validating archives, restoring an installation, and rotating a container-managed SECRET_KEY.
Backups are highly sensitive. An archive can contain user configuration, host information, the database, encrypted private keys, and the persisted application secret. Store it like a credential vault export.
The archive covers the persistent DATA_DIR state required to restore the instance. Transient logs, temporary uploads, incomplete transfers, and runtime-only SSH channels are excluded.
Current archives use format version 2. The verifier also understands legacy format version 1/schema 0 for compatibility. Validation checks the manifest, file checksums, declared sizes, member paths, member count, compression behavior, and archive-wide limits before restore.
An administrator can create a consistent backup while the service is online. SQLite uses its backup API and file writers are coordinated so that the archive represents a coherent point in time.
The completed download is one-time, session-bound, and expires after BACKUP_DOWNLOAD_TTL seconds, which defaults to 600. Temporary archive construction occurs outside DATA_DIR in an instance-specific namespace.
Do not rely on the short-lived browser download as retention. Move the archive immediately to encrypted, access-controlled backup storage.
Restore is deliberately disruptive and strongly confirmed:
- Upload the archive.
- Let WebSSH validate format and safety limits.
- Review the restore target and warnings.
- Complete both confirmations, including the exact
RESTOREphrase and administrator password. - WebSSH enters maintenance mode and stops accepting new work.
- Active sessions and transfers are closed.
- An emergency rollback archive is created.
- Persistent state is replaced and sessions are invalidated.
- The process terminates intentionally so the service manager can start a clean runtime.
If an interruption occurs during replacement, the restore workflow attempts rollback from the emergency archive. Still take an independent backup before every restore and keep it outside the instance.
CLI operations require every WebSSH process that uses the same DATA_DIR to be stopped. This avoids concurrent writers outside the coordinated web workflow.
Discover exact options in the installed version:
flask --app start:app backup create --help
flask --app start:app backup verify --help
flask --app start:app backup restore --helpFor a container deployment, execute the command in a one-off container with the same data volume and configuration, while the normal application container is stopped.
Default operational limits include:
| Setting | Default |
|---|---|
| Upload size | 1 GiB |
| Operation timeout | 30 minutes |
| One-time download lifetime | 10 minutes |
| Archive members | 10,000 |
| Individual uncompressed file | 1 GiB |
| Total uncompressed content | 10 GiB |
| Compression ratio | 200:1 |
| Manifest size | 10 MiB |
Reverse-proxy body-size and timeout settings must allow the same operation. Do not raise limits without assessing disk exhaustion and decompression-bomb risk.
The supported rotation command re-encrypts persisted secrets when WebSSH manages DATA_DIR/secret_key:
flask --app start:app rotate-secret-key --helpAll WebSSH processes must be stopped. Take and verify a backup first. The command changes the root used for encrypted per-user SSH keys and invalidates signed session state, so a partial or interrupted manual replacement can make persisted credentials unreadable.
If SECRET_KEY comes from an external environment variable or secret manager, rotating only the external value is not sufficient. Plan a controlled migration that keeps the old key available while persisted secrets are re-encrypted. The built-in command is scoped to the container-managed persisted secret.
Test the full sequence on an isolated instance:
- Create and download a backup.
- Verify it with the CLI.
- Start a disposable instance with an empty data volume.
- Restore the archive.
- Confirm local, LDAP/OIDC where applicable, Passkey, SSH, SFTP, and host-key data.
- Confirm that old browser sessions are invalid.
- Record the observed recovery time and required secret material.
An untested archive is not a verified recovery capability.
WebSSH documentation - Project - Issues - Discussions - Security
WebSSH Wiki
Install and operate
- Installation from Source
- Docker and Docker Compose
- Production Deployment
- Reverse Proxy and Subfolder Deployment
- Upgrading, Rollback, and FAQ
Identity and access
- Users and Account Management
- Authentication Overview
- LDAP and Active Directory
- OpenID Connect
- Passkeys and Recovery Codes
SSH and files
- SSH Connections and Host Keys
- Profiles, Jump Hosts, and Commands
- Terminal and Persistent tmux Sessions
- SFTP File Workspace and Transfers
- Tailscale SSH
Reference and administration