Open a shell in a running job
Logs tell you what a job chose to print. Sometimes you need to look at the running process itself — what is on disk, what the environment actually contains, whether the thing you expected to be listening is listening.
Runtime SSH gives you a shell inside one of your own running jobs.
Runtime SSH is available on Starter, Team, and Enterprise. It is a Preview capability: the behaviour below is supported, but the relay that carries managed sessions runs as a single instance, so access can be briefly unavailable during maintenance. Your job keeps running and is unaffected when that happens.
Before you start
You need:
- a job that is currently running — check with
proof liskov application status APP_REF; - an SSH key pair you control. Liskov never sees the private half;
- the public half declared in your Application manifest; and
proof-cli-liskovinstalled, signed in, with your organization selected.
If you do not have a key yet:
ssh-keygen -t ed25519 -f ~/.ssh/liskov-runtime -C "liskov runtime ssh"
Keep the private file readable only by you. Liskov reads only the public half, from your manifest.
1. Declare who may connect
Add the public key to your Application manifest and publish it. Access is bound to the manifest, so changing who may connect is a publish, not a console toggle.
{
"ingress": {
"ssh": {
"mode": "required",
"provider": {
"kind": "liskov",
"authorizedKeys": [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... liskov runtime ssh"
]
}
}
}
}
"kind": "liskov" uses the Liskov-operated relay, which needs nothing from you
beyond the key. To use your own Tailscale network instead, see
Bring your own Tailscale network.
Publish as usual. The next job launched from this manifest accepts that key; jobs already running were launched under the previous manifest and do not.
2. Check the connection before you use it
--print-command resolves and verifies everything without opening a session or
consuming an access ticket. Run it first — it is the cheapest way to confirm the
job is reachable.
proof liskov ssh APP_REF \
--identity ~/.ssh/liskov-runtime \
--print-command --json
You get the attachment, the deployment and job it is bound to, the host fingerprint, your key fingerprint, and the verified digests of the helper and SSH server Liskov placed in the runtime. No ticket is issued.
3. Connect
proof liskov ssh APP_REF --identity ~/.ssh/liskov-runtime
The first connection to a job shows its host key and asks you to confirm it.
Accept it once and it is pinned; a later mismatch is refused rather than
re-prompted, so a second prompt for a job you have already trusted is a
warning, not a formality. Add --accept-host-key to trust the first key
without prompting in scripts.
You get an ordinary interactive shell. Your customer process keeps running alongside you.
Pick an exact target with --deployment or --job when an Application has more
than one running job.
Verify it worked
Inside the session:
tty # /dev/pts/0 — you have a real terminal
uname -m # aarch64 — you are on the processor, not your laptop
Then, back on your machine, confirm the access was recorded:
proof liskov application activity APP_REF
Every connection appears in your activity feed — access granted, session opened, and session closed with its duration and how much data moved. That record exists so you can audit access to your own runtimes, including access by Liskov support.
What you can run in there
The runtime is a minimal Debian image plus your application. Core tools are
present: ls, cat, grep, find, sed, awk, tar, ps-less process
inspection through /proc, and pidof.
Some familiar tools are not installed, including ps, top, curl,
wget, and editors. To list processes:
for p in /proc/[0-9]*; do pid=${p#/proc/}; printf "%-6s %s\n" "$pid" \
"$(tr '\0' ' ' < $p/cmdline 2>/dev/null | cut -c1-60)"; done
Do not install packages. The runtime's contents are digest-verified, and installing at runtime breaks that guarantee for the rest of the job's life. If you need a tool permanently, add it to your image and publish.
Bring your own Tailscale network
If you already run Tailscale, you can have the job join your own tailnet instead of using the Liskov relay. Traffic then goes directly between your machine and the job over your network, and Liskov is not in the path.
This needs a Tailscale integration on your organization first, then a manifest that names it:
{
"ingress": {
"ssh": {
"mode": "required",
"provider": { "kind": "tailscale", "integrationId": "int-...", "port": 22 }
}
}
}
An integration belongs to exactly one organization and cannot be used by another.
When something is wrong
runtime_ssh_attachment_not_ready — the job has not finished preparing SSH,
or it has already ended. Check it is still running with
proof liskov application status APP_REF. A job that reached its scheduled end
is gone; launch a new one.
A host-key mismatch warning — stop. The key pinned on your machine does not
match the job answering. Do not override it. Re-run with --print-command --json and compare the fingerprint against the activity feed for that job.
runtime_ssh_plan_required — the Application's organization is on a plan
that does not include Runtime SSH.
Your session ends by itself — sessions have a maximum duration and an idle heartbeat. Reconnecting is normal and safe; it issues a fresh one-time ticket.
What this does not do
- It does not change your job's lifecycle. Connecting, disconnecting, or losing SSH does not restart, replace, or extend it.
- It does not give Liskov the ability to authenticate as you. Your private key never leaves your machine.
- It is not inbound ingress. It does not publish a port or serve traffic to anyone; see the capability matrix for hosted ingress, which is not part of v1.
Next
- Read logs and activity — including the record of every SSH session.
- Capabilities and limits — the availability owner for this feature.