Remote development with VS Code

VS Code Remote-SSH lets you open a workspace that lives on a remote machine and edit it as if it were local. It drives your system's ssh binary, so it works through Mezite the same way any other native SSH tool does: msh generates an SSH config stanza with a ProxyCommand, and the editor connects through it with a short-lived certificate. No static keys, and every session is authorized by RBAC and recorded for audit.


Prerequisites

  • The msh client installed locally and on your PATH (Remote-SSH invokes it from the generated ProxyCommand).
  • The Remote - SSH extension installed in VS Code.
  • A role that grants you access to the target node and enables port forwarding (see Administrator setup below).

1. Log in and generate your SSH config

Authenticate to the cluster, then write the per-node SSH config stanzas. msh config --append adds them to your ~/.ssh/config so the editor picks them up automatically.

Set up SSH config bash
# Authenticate (issues a short-lived certificate).
msh login --proxy mezite.example.com:3080 --user alice

# Write Host stanzas for every node you can reach into ~/.ssh/config.
msh config --append

Each generated stanza points ProxyCommand at msh proxy ssh and references your issued certificate and the cluster's host CA, so host keys are verified — nothing is set to "ignore". Re-run msh config --append after new nodes are enrolled.


2. Turn off VS Code's local server mode

Set Remote.SSH: Use Local Server to false in your VS Code settings.

settings.json json
{
  "remote.SSH.useLocalServer": false
}

With local-server mode on, VS Code opens an extra background SSH connection to manage the remote and assumes it can reuse a single multiplexed control socket. That interacts poorly with a ProxyCommand that mints a fresh certificate per connection. Turning it off makes Remote-SSH establish each connection directly through your ProxyCommand, which is the supported path.


3. Connect

Open the Command Palette, choose Remote-SSH: Connect to Host…, and pick the node by the name from your SSH config (for example web-server-01.mezite). Remote-SSH reads the Host stanza, runs the ProxyCommand, installs its server component on the node over the resulting connection, and opens the workspace. Behind the scenes the editor opens a local port forward (ssh -L) to its server component on the node — this is why the port_forwarding role option is required.

Other editors work the same way as long as they drive the system ssh client or support a ProxyCommand. Anything in that family — including Cursor and JetBrains Gateway — connects through the same generated config. Zed works out of the box: point its remote connection at the same Host alias.


Reconnecting after a certificate expires

Mezite certificates are short-lived by design. An already-open session keeps working past expiry — keepalives hold idle connections open (see below) — but starting a new connection with an expired certificate fails. If Remote-SSH cannot reconnect (for example after your laptop wakes from sleep and the editor tries to re-establish the link), the fix is simply to refresh your certificate:

Refresh your certificate bash
msh login --proxy mezite.example.com:3080 --user alice

Then retry the connection from VS Code. There is no need to regenerate your SSH config — the same stanza picks up the new certificate from disk.

Idle sessions and keepalives

Mezite sends server-side keepalives on every leg of a connection so an idle editor session is not dropped by a load balancer or NAT timeout. The defaults send a keepalive every 5m and give up after 3 unanswered probes, so a genuinely dead peer is reaped after roughly 15 minutes while a live-but-quiet session stays up indefinitely. Operators can tune ssh.keep_alive_interval and ssh.keep_alive_count_max — see the SSH Access guide.


Administrator setup

Allow port forwarding

Remote-SSH's editor↔server tunnel uses SSH local port forwarding, which is gated by the port_forwarding role option. The built-in admin and ssh-access roles enable it. For a custom role, set it explicitly:

Role enabling port forwarding yaml
kind: role
metadata:
  name: developers
spec:
  options:
    max_session_ttl: 8h
    port_forwarding: true
  allow:
    logins: ["ubuntu"]
    node_labels:
      env: ["dev"]

If none of a user's roles enable it, the forwarding channel is refused and an access.denied.port_forwarding audit event is recorded — Remote-SSH will fail to bring up its server component. A granted forward records a port_forwarding.start event with the target address. Forwarded traffic itself is not session content and is not recorded.

Optional: hard cutoff at certificate expiry

By default a live session survives certificate expiry, which is convenient for long editor sessions. If your environment needs a hard cutoff, set disconnect_expired_cert: true on a role: the session is forcibly disconnected the moment the certificate expires (the user re-runs msh login to continue). The option OR-combines across a user's roles. See the Roles & RBAC reference for the full list of session options.