Remote SSH access#
You can let users connect to their hub session with SSH for terminal work, VS Code Remote, or file transfer with scp/rsync. This runs an SSH server inside the same user container and exposes it over HTTPS.
How it works#
jupyter-sshd-proxystartssshdinside the user server and publishes it throughjupyter-server-proxyat/sshd/over WebSockets.Authentication and authorization come from JupyterHub - no extra inbound ports or firewall changes are needed.
The SSH session uses the same CPU, memory, and storage limits as the Jupyter server.
User image requirements#
Install the following in the user image (see Customize your user environment):
openssh-serverjupyter-sshd-proxyjupyter-server-proxy
Example values.yaml profile:
jupyterhub:
singleuser:
profileList:
- display_name: "SSH enabled"
slug: "ssh"
kubespawner_override:
image: "quay.io/yuvipanda/pangeo-jupyter-sshd-proxy:latest" # includes jupyter-sshd-proxy
You can also add these packages to your own image instead of using the example image above.
Local setup (users)#
Install a WebSocket helper for your SSH client (recommended:
websocat).Create a JupyterHub API token from
/hub/tokenon your hub.Add an SSH config entry in
~/.ssh/config(replace placeholders):
Host myhub
HostName <your-hub-hostname> # e.g., myhub.pilot.2i2c.cloud
User jovyan
ProxyCommand websocat --binary -H="Authorization: token <API_TOKEN>" asyncstdio:wss://%h/user/<JUPYTERHUB_USERNAME>/sshd/
Then connect with ssh myhub or point VS Code Remote - SSH at the myhub host. The ProxyCommand is reused by scp and rsync.
Keep these tokens private!
Keep the API token private and rotate it from /hub/token if it is exposed.
Community examples#
Openscapes (https://openscapes.org/) uses this workflow for VS Code Remote and large data transfers
Configuration pull request: Openscapes/openscapes.cloud#67
See also
jupyter-sshd-proxy repository - setup and troubleshooting
VS Code Remote - SSH - connect the VS Code client to the SSH host
Not Just for Notebooks: JupyterHub in 2025 - talk covering SSH access and other interfaces for JupyterHub
Acknowledgements#
This guide was originally written by Andy Teucher for OpenScapes and its content was modified for these docs.