Skip to content

deploy: ship the vault dependency, keep it opt-in - #106

Merged
dolonet merged 3 commits into
dolonet:mainfrom
gorevds:feat/vault-on-by-default
Jun 11, 2026
Merged

deploy: ship the vault dependency, keep it opt-in#106
dolonet merged 3 commits into
dolonet:mainfrom
gorevds:feat/vault-on-by-default

Conversation

@gorevds

@gorevds gorevds commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

Problem

The encrypted credential vault (the "Save this connection" UI) is gated on WEBSH_VAULT_ENABLE=1 and the optional cryptography dependency (server.py: vault_enabled = HAS_CRYPTOGRAPHY and WEBSH_VAULT_ENABLE and not _vault_disabled). The shipped deploy artifacts provided neither:

  • websh.service and the Dockerfile did not set WEBSH_VAULT_ENABLE.
  • cryptography was not declared as a dependency anywhere (no requirements.txt / pip install), so even setting the flag did nothing on a clean python:3-slim image.

Net effect: an operator deploying the bundled unit or Docker image got no saved-credential UI even though the feature is fully implemented.

Change

Make the vault work out of the box for the bundled deploy paths, while a bare python3 server.py stays opt-in (the in-code default is unchanged):

  • requirements.txt (new): declare cryptography>=3.4.8 (the documented floor from encryption.md).
  • Dockerfile: pip install -r requirements.txt; set WEBSH_VAULT_ENABLE=1; point WEBSH_CREDS_PATH at a websh-owned /data volume — the default cwd path (/app) is not writable under USER websh, and the volume lets saved credentials survive container replacement.
  • websh.service: set WEBSH_VAULT_ENABLE=1 + WEBSH_CREDS_PATH=/var/lib/websh/websh.creds.json, and add StateDirectory=websh so that path is writable despite ProtectSystem=strict / ProtectHome=read-only.
  • docs: update configuration.md, encryption.md (status + quick-start) and the systemd install steps to reflect the new default.

Failure stays graceful: a host without cryptography still runs, with the saved-credential UI hidden.

Verification

  • python3 test_server.py472 OK (skipped=1).
  • The systemd configuration was validated live on a hardened deployment (same ProtectSystem=strict / ProtectHome=read-only unit): with StateDirectory=websh + WEBSH_CREDS_PATH, /api/config reports vault_enabled: true, a save returns 200 and writes /var/lib/websh/websh.creds.json at mode 0600, and save_delete returns 204 and reaps the entry. Without the writable path the save fails (cwd / is read-only), which is exactly what this PR fixes.
  • The Docker image was not built in CI here; the image config mirrors the validated systemd setup (cryptography installs from a manylinux wheel on python:3-slim; /data is websh-owned and writable).

gorevds and others added 2 commits June 7, 2026 11:37
The encrypted credential vault (saved SSH credentials) is gated on
WEBSH_VAULT_ENABLE=1 plus the optional cryptography dependency. Neither
was supplied by the shipped deploy artifacts, so operators using the
bundled systemd unit or Docker image got no saved-credential UI even
though the feature is complete — and cryptography was never declared as a
dependency, so even setting the flag alone did nothing on a clean image.

Make it work out of the box for the bundled deploy paths while leaving a
bare `python3 server.py` opt-in:

- requirements.txt: declare cryptography (>=3.4.8, the documented floor).
- Dockerfile: install requirements; set WEBSH_VAULT_ENABLE=1; point
  WEBSH_CREDS_PATH at a websh-owned /data volume (the default cwd path is
  not writable under USER websh) so saved credentials persist.
- websh.service: set WEBSH_VAULT_ENABLE=1 and WEBSH_CREDS_PATH, and add
  StateDirectory=websh so /var/lib/websh is writable despite
  ProtectSystem=strict / ProtectHome=read-only.
- docs: reflect the new default in configuration.md, encryption.md and
  the systemd install steps.

The in-code default stays off, so dev / library-style use is unchanged.
Declaring `cryptography` nowhere meant the credential vault was impossible
to enable in the bundled Docker image and systemd unit even with
WEBSH_VAULT_ENABLE=1 set — the HAS_CRYPTOGRAPHY gate kept it off. Ship the
dependency (requirements.txt + install steps) and pre-provision a writable
creds path (Docker /data volume, systemd StateDirectory) so enabling the
vault is a one-line opt-in, but leave WEBSH_VAULT_ENABLE off by default:
turning persistent server-side credential storage on is an operator's
decision, not a packaging side effect.

Also fix the manual-install dependency step (PEP 668 makes a bare
`pip install` fail on Debian/Ubuntu's externally-managed Python) and
document Docker volume persistence.
@dolonet dolonet changed the title deploy: enable the credential vault by default in bundled deployments deploy: ship the vault dependency, keep it opt-in Jun 11, 2026
@dolonet

dolonet commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Pushed a follow-up commit (6eb47a0) that keeps the packaging fix here but drops the default-on flip. Happy to talk it through if you'd rather keep it on by default — didn't want to override silently.

The core fix is right and worth shipping: cryptography was declared nowhere, so the vault was impossible to enable in the bundled image/unit even with WEBSH_VAULT_ENABLE=1 set — the HAS_CRYPTOGRAPHY gate kept it off. Declaring it in requirements.txt and installing it in both artifacts closes that.

What changed in the follow-up:

  • Kept requirements.txt, the install steps, and the writable creds path (Docker /data volume, systemd StateDirectory), so enabling the vault stays a one-line opt-in.
  • Dropped the WEBSH_VAULT_ENABLE=1 defaults in websh.service and the Dockerfile. Flipping bundled deployments to persist encrypted SSH credentials server-side is a security-posture decision an operator should make explicitly, not inherit from a packaging fix — so the vault stays off by default with the dependency pre-bundled.
  • Fixed two edges along the way: the manual-install pip install fails on Debian/Ubuntu's externally-managed Python (PEP 668) → switched the doc to apt install python3-cryptography; and documented -v websh-data:/data so Docker creds persist across container replacement instead of landing in a throwaway anonymous volume.

Docs (encryption.md, configuration.md, deployment.md) updated to match.

# Conflicts:
#	Dockerfile
#	docs/configuration.md
#	docs/deployment.md
@dolonet
dolonet merged commit 5619687 into dolonet:main Jun 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants