SSH access and certificates#
Every development environment, and a notebook's runtime with SSH into the
runtime too, runs an SSH server. You reach it with astra ssh, with
ssh, scp and rsync, and with editors that speak SSH — without an open
port, a bastion, an account on the machine or a key to hand out. This page
explains how, and what a session may do.
Into the container, never the machine#
flowchart LR
S[ssh on your computer] -->|ProxyCommand<br/>astra ssh --proxy| A[Astralyx]
A -->|the machine's own<br/>outbound connection| M
subgraph M[Machine]
D[SSH server on 127.0.0.1:2222<br/>inside the runtime's container]
end
- The server is the machine's. The machine's agent carries a static
OpenSSH and mounts it read-only into the container (at
/.astraeus/bin); your image needs no SSH server. It starts inside the container, listening on the container's own loopback,127.0.0.1:2222, and nowhere else. - The machine connects it. Your
sshtalks toastra ssh --proxy, which carries the bytes to Astralyx over HTTPS; Astralyx checks who you are and that you may use the runtime, then passes them over the connection the machine keeps open; the machine connects to the SSH server from inside the container's network. Nothing listens on the machine's network, and other containers on the machine cannot reach the server. - You land in the container. The machine itself is out of reach: no port, no host login, the server's files read-only, and the container no more privileged than without SSH.
Certificates, not keys#
There are no passwords and no authorized_keys: the SSH server accepts
only certificates signed by your workspace's SSH certificate authority.
astra sshmakes an Ed25519 key pair on your computer the first time, in~/.config/astra/ssh/<host>/. The private key never leaves your computer.- It sends the public key and asks for a certificate for that runtime
(
POST /notebook-runtimes/{name}/ssh-certificates). - The certificate authority signs it if you may use the runtime.
| Property | Value | Why |
|---|---|---|
| Valid | 8 hours (from 5 minutes before it is issued, for clocks that differ) | Short-lived: nothing to revoke. astra ssh renews it when less than 10 minutes are left. |
| Opens | That one runtime (principal runtime:<name>) |
A certificate for one environment opens no other, even another of yours. |
| Valid from | The container's own loopback only (source-address 127.0.0.1/32,::1/128) |
That is where the machine connects from: a copied certificate is of no use anywhere else. |
| Allows | A terminal, local port forwarding, agent forwarding | What editors' Remote-SSH and git push with your own keys need. |
| Key id | hesperus:<runtime>:<user> |
The server logs it with each login: who it was. |
Each workspace has its own certificate authority, made the first time someone asks. Its signing key is kept by Astralyx and never served; only its public half is given to the runtimes, to check certificates.
Host keys#
Each runtime makes its SSH host key once and keeps it on its drive
(/content/.hesperus/ssh/<runtime>/), so it is the same after every
restart. astra ssh trusts it on first use and remembers it in
~/.config/astra/ssh/known_hosts under the runtime's host name: ssh warns
only if it changes.
Host names#
astra ssh config writes a host for each runtime you own into
~/.ssh/config: <runtime>.<cluster>.<workspace>.<org>.astra, such as
dev.lab-a.vision.acme.astra. Everything that speaks SSH connects by that
name: ssh, scp, rsync, VS Code's and Cursor's Remote-SSH, JetBrains
Gateway. The name is resolved by astra, never by DNS. See
Connect VS Code, Cursor or JetBrains Gateway.
Who may connect#
| Who | May connect |
|---|---|
| The runtime's owner (who made it, or whom an admin made it for) | ✓ |
| The people it is shared with (its members) | ✓, with their own certificates |
| The workspace's admins | ✓, any runtime |
| Another editor of the workspace | — 403 SSH_FORBIDDEN |
| Viewers | — whether shared with or not |
The rule is checked when a certificate is asked for and again for every connection, before any byte reaches the machine. Taking someone off the members refuses their next connection; a session already open runs until it closes. See Members and limits.
A runtime without SSH answers 409 NOTEBOOK_CONFLICT runtime … has no SSH
(turn it on: ssh.enabled).
What a session gets#
- The login.
ssh.user(Log in as), which must exist in the image:rootby default in an environment,jovyanin a notebook's runtime on a Jupyter preset. The container runs as root when SSH is on, so any user of the image can be the login. - The home. An environment's login has its home on the drive,
/content/home/<user>: dotfiles, shell history and editors' servers outlive the container. A notebook's runtime keeps the image's home (/root,/home/jovyan), which is lost when it stops: work under/content. - The container's environment. Sessions get the image's variables —
PATH, CUDA's, conda's, a runtime's credential variables — but never the runtime's own token. - What is allowed. A terminal, commands,
sftp(soscpandrsync), local port forwarding (ssh -L) and agent forwarding. Remote forwarding, X11 forwarding and tunnels are off.
A sandboxed runtime (isolation: sandbox, gVisor) cannot have SSH:
spec.ssh: SSH needs standard isolation.
A shell is the container
A session has what any process in the container has: its files, its GPUs, the values of the credentials given to it as variables. That is why only the owner, the people they share it with and admins get one. Log masking applies to runs' logs, not to what a terminal shows.
Each connection is recorded — who, from what, when, for how long, never what was typed. See Sessions and audit.