Web-SSH & access
Browser shells with no open port 22, ephemeral short-TTL keys, per-server grants, and audited sessions — managed, keyless-by-default access to your whole fleet.
Web-SSH & access
HostSSH is named for the thing it makes effortless: getting onto your servers.
Instead of "a thing you configure" — open :22, scatter authorized_keys, hope
nobody copied a private key — HostSSH turns SSH into managed, audited,
keyless-by-default access. You connect through the agent over a tunnel, with
short-lived keys minted on demand and a record of who went where.
- No open port 22. Access rides the agent and a Cloudflare Tunnel — the server keeps no inbound SSH port exposed to the internet.
- No shared root keys. Keys are issued per user and per team, rotated and revoked centrally, and the short-TTL ones expire on their own.
- Per-server, per-user grants. Access is a grant you give, not a key you hand out.
- Everything is audited. Who connected to which server, when — with optional full session recording for compliance.
Requires the Access connection (Cloudflare Tunnel or Tailscale) and a Solo tier or higher. See Connections (BYOK) and Licensing.
Why keyless-by-default
A long-lived private key on a laptop is the thing that gets stolen, screenshotted, committed to a repo, or left behind when someone leaves. HostSSH's default is the opposite: there is no standing key to steal.
| The old way | HostSSH |
|---|---|
:22 exposed (or behind a fragile bastion you maintain) | No open port — access via the agent + tunnel |
| One root key copied to every laptop | Per-user, per-team keys; revoke one without touching the rest |
| Keys live forever until someone remembers to rotate | Ephemeral keys with a short TTL, minted on demand, auto-expiring |
| Access = whoever has the key | Access = an explicit grant on a specific server, removable instantly |
| No record of who logged in | Audited sessions, optional recording |
How keyless really works (a certificate authority)
"Keyless" isn't a key you keep somewhere safer — it's no standing credential at all. When you open a
shell, HostSSH's control plane acts as a certificate authority: it mints a fresh ed25519 certificate
that is good for ≤5 minutes, scoped to that one server, for one principal. The agent trusts
only the HostSSH CA — there are no authorized_keys on the box to steal, screenshot, or leave behind.
When the certificate expires (or you close the tab), access is simply gone.
- Step-up verification. Opening a session prompts a passkey / WebAuthn check — phishing-resistant, per-session.
- Root is a separate grant. The default principal is a non-root user; root is an explicitly-granted, passkey-gated capability (with an optional second-approver on production servers).
- Recorded, tamper-evident. Sessions are recorded to your own storage as a continuous, hash-chained trail — a gap in the chain is itself an alarm.
- Instant kill-switch. Revoking a session ends it immediately and reaps the shell; the ≤5-minute lifetime is the backstop.
Open a shell from the dashboard
The fastest path — no client, no key file, just a browser tab.
- Open your fleet at hostssh.com and pick the server.
- Click Web-SSH (or Open shell). HostSSH brokers the connection through the agent over the tunnel and mints a short-TTL key scoped to this session.
- A terminal opens in the browser. Work as usual.
- Close the tab to end the session. The ephemeral key expires; the audit log records the session (start, end, and — if enabled — a full recording).
Nothing about this opens a port on the server: the shell is relayed through the
Access connection, so :22 stays closed to the world.
You can also reach the server-local admin panel the same keyless way — it binds
to 127.0.0.1:8765 and is exposed safely through the panel's tunnel, never by
opening a port. See Install.
Jump from the CLI
If you live in a terminal, the same gateway is one command away:
hostssh ssh <server> # jump to any fleet server via the gateway
hostssh ssh uses the tunnel and mints an ephemeral, short-TTL key for the
session — the same keyless path as the browser shell, no ~/.ssh/config entry and
no standing key required. It is HostSSH acting as bastion / jump-as-a-service:
you authenticate to HostSSH, HostSSH brokers you onto the box, and the grant +
session are recorded.
hostssh status # confirm the server is reachable and licensed
hostssh ssh app-prod # open an audited, keyless session
Centralized key management
Keys are managed from the control plane, not copied around by hand.
| Action | What it does |
|---|---|
| Issue | Mint a key for a user or team, scoped to the servers they're granted |
| Rotate | Roll a key without disturbing others — no fleet-wide authorized_keys edit |
| Revoke | Kill a key immediately; the next connection attempt fails |
| Ephemeral | Short-TTL keys minted on demand for a single session, then auto-expire |
There are no shared root keys. Because each grant maps to a person or team, offboarding is one revoke — not a scramble to find every box a departed contractor could still reach.
Per-server, per-user grants (bastion as a service)
Access is modeled as a grant: this user (or team) may reach this server. HostSSH is the bastion that enforces it — so you don't stand up, harden, and patch a jump host yourself.
- Grant or remove access per server, per user from the dashboard.
- A grant is what authorizes the Web-SSH shell and
hostssh ssh— no grant, no shell. - Removing a grant takes effect on the next connection attempt, fleet-wide.
This is what the INTERFACES spec calls the cross-cutting
"get me onto the box" surface: the same broker backs the dashboard, the CLI, and
(for AI-driven ops) the MCP ssh_exec tool.
Audited sessions & recording
Every access path is logged: who connected to which server, and when. For environments that need more than a connection log, turn on session recording to capture the full session for later review — a SOC2/compliance-friendly trail kept per organization (see Security).
- Connection audit is always on: user, server, grant used, timestamps.
- Session recording is optional, enabled per server or per grant.
- Audit entries live alongside the rest of your org's audit log (activations, captures, restores, migrations).
How it works (the short version)
You ──▶ HostSSH gateway ──▶ Cloudflare Tunnel ──▶ Agent ──▶ shell on the server
(authn + grant) (no open :22) (root on host)
The agent already runs on every managed server and is the only component that
touches the host. Web-SSH and hostssh ssh ride that same agent through the tunnel
from your Access connection, mint a short-TTL key for the session, enforce the
grant, and write the audit record. No inbound SSH port is ever required — egress to
the tunnel is enough. See Architecture for the full picture.
Set up access
- Add an Access connection. Connect a Cloudflare Tunnel (
tunnel_token) or Tailscale (auth_key) under Connections → Access. Scope the Cloudflare tunnel to the dashboards/Web-SSH only; for Tailscale, use an ephemeral, tagged-ACL key. Details in Connections (BYOK). - Grant users. From a server's page, grant Web-SSH access to the users or teams who need it.
- Connect. Open Web-SSH in the dashboard, or run
hostssh ssh <server>.
Tier note. The Access connection (and therefore Web-SSH) is available on Solo and above — it's part of the same set as Notifications, Monitoring, and config-as-code. The single source of truth for tiers is Licensing.
Notes & roadmap
- Cross-link: the Access connection's capability tags (
tunnel,web_ssh,mesh_access) and least-privilege guidance are defined in Connections (BYOK). - Tailscale path: Tailscale grants overlay (
mesh_access) reachability to the agent and dashboard without exposed ports; Cloudflare Tunnel powers the browser Web-SSH terminal (web_ssh). - Phase note: the browser Web-SSH terminal, centralized key issuance/rotation, and optional session recording are part of the SSH-gateway surface described in INTERFACES §4. Capture/restore/relocate and the CLI jump come first; richer key-management UI and recording land alongside the gateway. Until then, point your Access connection at a reachable tunnel to exercise the path.