Release notes
On this page
The changes in each LWS release that affect people running it. The full list of pull requests for every version is on the GitHub releases page.
Not yet released
Merged into main after 1.4.3:
- Command injection over SSH. OpenSSH joins the arguments of a remote
command into one string for the host’s shell. The remaining commands that
did not go through LWS’s hardened SSH helper now do:
px reboot,px exec,px upload, the Compose file transfers inapp deployandapp update, and the file copies in the backup commands. Values that end up in remote commands, such as--target-host,--storageand thelxc cloneoptions, are now checked against allow-lists. lxc runquotes its free-text options (--hostname,--password,--net0,--ip,--gateway,--dnsand others) before they reach the remote shell.- Web UI. API responses are rendered as text instead of HTML, which closes
a cross-site scripting hole in
ui.html. lxc execran everything after a&&,;or|on the Proxmox host instead of in the container. The command now reaches the container as one argument list; usesh -c '...'for shell syntax.- Timeouts. Remote commands were stopped after 60 seconds and started
again up to twice, which cut off and repeated backups, package installs and
migrations. The limit is now
ssh_command_timeout(3600 seconds by default,0for none), a command that timed out is never run again, and only failed connections are retried. The API’s limit isapi.command_timeout. px updatenever updated a host. It now runsapt-get dist-upgradeon the selected host after a confirmation (--yesskips it).- Security groups use the Proxmox API (
pvesh) instead of editing files.security-group-attachused to add the group as a disabled rule; it now enables it, and--enable-firewallturns on the container’s firewall.security-group-rmrefuses a group that still has rules unless--force, andsecurity-group-rule-rmremoves exact matches only. - Backups.
lxc backup-createfailed on every run (--compress 6is not a vzdump value); it now takes--compress zstd|gzip|lzo|none,--modeand--storage.lxc backup-restorerestores vzdump archives withpct restoreand no longer deletes the backup afterwards. Without--storage, it usesdefault_storage.px backupcreates its directory on the Proxmox host, where the archive is written, andconf backupcopiesconfig.yamlas it is, comments included, and fails when there is noconfig.yaml. - Scaling. The example thresholds were written as percentages, so
lxc scale-checkalways suggested more; values above 1 are now read as percentages.scale-checkno longer suggests a smaller disk, which Proxmox cannot apply, and ends with the exactlxc scalecommand to run.lxc scale --storage-sizegrows the disk withpct resize, and--net-limitkeeps the rest of the network settings. - CORS.
config.yaml.exampleno longer allows the"null"origin. The web UI is served by the API and needs no CORS entry. - Docker apps.
app setupinstalls Docker and Compose from the container’s package manager and checks thenestingandkeyctlfeatures (--enable-nestingsets them).app deploykeeps each Compose file in/opt/lws/apps/<name>/, and--auto-startinstalls a systemd unit inside the container instead of on the host. lxc run --passwordno longer passes the root password topct create, where it showed in the Proxmox host’s process list and in LWS’s debug logs. The password is set withchpasswdinside the container once it runs, read from standard input.- Other commands.
lxc rungains--featuresand--unprivileged;lxc cloneremoves its temporary snapshot;lxc migrategains--restartand--target-storage;lxc health-check --fixno longer runs placeholder commands;lxc netchecks UDP ports with UDP. - API. Passwords no longer appear in
api.log, error responses no longer include exception text, and the Swagger page’s “Try it out” calls the right URLs. - Configuration.
config.yaml.exampledrops the scaling, discovery andminimum_resourceskeys that no command read. Existing files load unchanged.
1.4.3 (2 October 2026)
- SSH host keys are now checked:
StrictHostKeyChecking=accept-newtrusts a host on first contact and refuses a changed key afterwards. Before, any key was accepted. - SSH passwords are passed to
sshpassthrough the environment instead of the command line, so they no longer show up in the process list. - Input validation: instance IDs, group names, protocols, ports and IP addresses are checked before they are used in remote commands.
- Exit codes: the bulk
lxccommands and 44 other failure paths now exit with a non-zero status, so the REST API reports those failures as errors. lxc execkeeps quoted arguments that contain spaces intact.- REST API: CORS denies cross-origin requests unless
allowed_originslists them; the server runs on waitress unlessdebugis set, and the Werkzeug interactive debugger is never enabled. - Docker image now includes the
lws_corepackage andsshpass, which the API needs to run commands.
1.4.2 (9 September 2026)
- The REST API refuses to start without a real API key, and the example
configuration binds it to
127.0.0.1. An emptyapi_key, or one of the placeholders that shipped in the repository, stops the server at startup. Upgrading: setapi_keyto a random value of at least 32 characters, and setapi.hostexplicitly if the API has to listen on another address. - Python 3.10 or later is required, and CI tests every version from 3.10
to 3.14. The Docker image is based on Python 3.14 and runs as an
unprivileged
lwsuser. - No third-party requests from the documentation site and web UI: fonts and libraries are served from the repository.
- A debug message no longer includes file paths.
1.4.1 (8 November 2025)
- A pytest suite for the
lws_coremodules. - The documentation site in
docs/, published on GitHub Pages.
1.4.0 (8 November 2025)
- The shared code of
lws.pymoved into thelws_corepackage (configuration, SSH, Proxmox commands, logging, utilities). - The REST API no longer includes exception details in the error it returns when it cannot start a command.
1.3.0 (13 September 2025)
- A
Dockerfilefor running the REST API in a container. - Security and code quality fixes.
1.2.0 and 1.1.0 (5 May 2025)
Released without notes; the 1.1.0 and 1.2.0 comparisons list the commits.
1.0.0 (1 April 2025)
The first tagged release.