============================================================
Status: DESIGN v0.2, 2026-10-15 — Hermes's review (note 15) folded in. Nothing is wired yet. This is the "testing process to switch
between operating via SSH and secure tunnel only" (Matthew, 2026-10-15). The reason it exists: in development we
hold root SSH to the Client VPSes (they are the estate the apps are developed against), but the platform's
production posture is that a Client VPS has no standing login — maintenance runs on the VPS by the agent and
is reported outbound over the tunnel (patching design, §10). We must
be able to rehearse the production posture on the test estate, which means a reversible switch between the two.
Why it is permanent rather than a rehearsal phase (Matthew, 2026-10-15) — a ruling, recorded for this design.
The three boxes (test-client,test-client-dental,test-client-pharmacy) are a test estate and will remain
one: they are the estate the apps are developed against, including future versions, and they are the
canary for patching — a patch or an image refresh is proved on them before it reaches a real client's box, so
a faulty patch or a bug is not passed on to a client. The switch between SSH and tunnel-only access is therefore a
standing operating mode of that estate, not a one-off exercise: SSH while developing, tunnel-only as the
in-service posture and for maintenance, switched per VPS. What it rehearses is the posture a real client's
box is permanently in.
| SSH / dev mode | Tunnel-only / production mode | |
|---|---|---|
Our SSH key in the VPS's authorized_keys |
present | removed |
| Our access to port 22 | open | closed (firewalled) |
| The VPS's outbound reverse tunnels | up | up (unchanged) |
| Maintenance | direct login | agent + signed jobs, reporting outbound |
| Represents | development | what a real client gets |
The VPS's outbound tunnels, backup and (future) agent are unaffected by closing port 22 — they are all outbound.
And in SSH/dev mode the sign-in itself is key-only (2026-10-15). Both test-estate Client VPSes now
refuse password authentication (PasswordAuthentication no, PermitRootLogin prohibit-password — the
image shipped 50-cloud-init.conf with password auth on, so the hardening drop-in is named 00-:
sshd takes the first obtained value per keyword). The two postures therefore differ in whether our
key is authorised at all, not in whether some password might work. A real client's box never carries
our key; the dev boxes now carry nothing but it, and the whole hardening is one host-local
sshd_config.d/ file — part of the same reversible switch.
Only our ability to log in changes.
authorized_keys — the state that matters and the state that can be shown: our key line is either in theufw denies 22 in tunnel-only mode. Closing 22 breaks nothing we rely on.A toggle client-vps-access-mode.sh {ssh|tunnel} <client-vps> (to be built; run from the primary against the VPS),
with these non-negotiable properties:
ufw rule, thenPermission denied (the--dry-run that prints exactly what will change (the authorized_keys diff and the ufw rule).authorized_keys line bytes, not just a hash, so--status must work without logging in. A status command that needs SSH is useless in the mode it describes:authorized_keys hash before and after, and the failed-login output from both layer proofs.| Route | How | Notes |
|---|---|---|
| Hosting-panel console | provider VNC/serial console → log in without SSH | needs the account; unknown for the dental VPS |
| Documented re-provision | rebuild from the SIAAS blueprint, restore data | heaviest; last resort |
| One-time credential | owner/client issues a temporary credential, logged under temporary_credential |
the sanctioned SIAAS pattern (§10.6.3) |
Rehearse the route back where it can actually be proven. The GP VPS is the natural posture rehearsal (its key
is already revoked), but it is also the one where break-glass is least available — and its registry row does
record a hosting account while the dental one does not. So: rehearse posture on GP, but prove the route back on a
VPS where we can restore access — with the dental VPS's hosting account settled first, since that account is the
only route that survives closing port 22.
The two test-estate boxes are the estate's permanent exemplars of the two modes — a standing state, not a
snapshot of where we happen to be. The switch between them is the test estate's standing operating mode (ruling,
2026-10-15).
| Client VPS | Tenants | Mode (standing state) | Notes |
|---|---|---|---|
dental 194.164.18.33 |
test-client-dental, test-client-pharmacy | SSH / dev — the dev-mode exemplar | our key is authorised here by design; the ruling keeps it (it is not a cleanup candidate). Host of the WO-M4 swap; hosting account unknown |
GP 77.68.97.101 |
test-client | tunnel-only — the production-posture exemplar | our key was revoked 2026-08-11; the natural first tunnel-only rehearsal |