Open source · Apache-2.0 · GCP and AWS
Disposable cloud machines for coding agents.
Secure, cheap spot VMs in your own cloud account. No inbound ports, a relay that cannot read your traffic, and a lease on every machine so it deletes itself when the work is done.
- account
- yours
- class
- compute.large · spot
- public IP
- none
- inbound ports
- none
- host key
- issued before boot
- sudo
- locked
Example lease, shown as a time-lapse.
Why it exists
An agent needs a real machine. It should not be your laptop, and it should not live forever.
Built to be driven
JSON output, non-interactive exec, push, pull and forward. One manifest describes a machine an agent can ask for again and again.
Nothing to knock on
The VM has no public address. It dials out. Your SSH keys never leave your machine, and the relay in the middle holds none.
Spot, in your account
Spot capacity on your own bill, at your own negotiated rates. The price per hour and the cost of the whole lease are shown before launch.
A lease, not a pet
Every machine has an expiry. A timer inside the VM deletes it on time, whether or not anyone is still watching.
How it works
Three small programs, and one of them is deliberately kept in the dark.
Step through a launch. Watch where the keys are, and where they are not.
Security
Assume the relay is compromised. Here is what the attacker gets.
The relay is the only shared, internet-facing part. So it is designed to be worth as little as possible to whoever breaks into it.
It can
- Refuse or drop your connections
- See connection metadata: addresses, timing, byte counts
- Open a TCP connection to your VM's sshd, and fail to log in
- Serve a different agent binary, which the VM then rejects
It cannot
- Read or change your commands, files or forwarded traffic
- Pretend to be your VM. The host key was fixed before boot
- Log in. It never holds a key, and passwords are off
- Run code on the VM, or reach anything in your cloud account
We also publish what the design does not cover. The known limits are in the threat model, next to the code that backs each claim.
No trust on first use
The CLI issues the VM's host key before the VM exists and pins it on every connection.
cmd/runlease/exec.go · FixedHostKeyVerified agent
The boot script checks the agent's SHA-256 against the one compiled into the CLI, then runs it.
pkg/userdata/userdata.goUnprivileged by default
The agent runs with no capabilities. sudo on the VM is locked unless the manifest opts in.
pkg/userdata/userdata.goRelay fails closed
It will not start without authentication, validates every token and caps its slots.
pkg/relay/server.goHardened sshd
Public key only, one allowed user, no root login, one ed25519 host key.
pkg/userdata/userdata.goSigned releases
Checksums signed with Sigstore, build provenance for every binary, actions pinned by commit.
.github/workflows/release-please.ymlUsage
One binary. A handful of verbs.
- Portable sizescompute.small to compute.2xlarge and compute.gpu map to the right type on each cloud.
- Many sessions, one tunnelHold a port forward open in one terminal and run exec, push and pull from others.
- Bring your own relayOne static binary behind TLS. Or use no relay and connect directly, through IAP, or through SSM.
# a spot VM in your account, deleted in two hours $ runlease up --provider gcp --size compute.large --ttl 2h # see what is running $ runlease list # need longer? move the timer $ runlease snooze agent-box 1h # done early $ runlease down agent-box --yes
# run a command $ runlease exec agent-box -- make test # reach a port on the VM from localhost $ runlease forward agent-box -L 8080:localhost:8080 # move files over the same channel $ runlease push agent-box ./build.tar /tmp/build.tar $ runlease pull agent-box /var/log/app.log ./app.log # or just open a shell $ runlease connect agent-box
# agent-box.yaml name: agent-box provider: gcp region: us-central1-a instanceClass: compute.large reclaim: ttl: 3h selfTermination: true relay: addr: wss://relay.example.com setup: - name: toolchain run: apt-get update && apt-get install -y build-essential git $ runlease up -m agent-box.yaml --attach
# machine-readable output $ runlease up -m agent-box.yaml --detach --output json $ runlease list --output json # no TTY, no prompts $ runlease exec agent-box -- ./run-tests.sh $ runlease down agent-box --yes # and if the agent forgets to clean up, # the lease does it anyway
The relay
Start on ours for free. Move to your own whenever you like.
The relay is the one piece that needs a public address. Use the shared one with a Google sign-in, or run the same binary yourself. Either way it never holds your keys.
Public relay
Sign in with Google and launch. No card, no setup.
- machines at once
- 2
- connected for up to
- 8 h
- sign-in
- price
- free
$ runlease config set relay.addr \ wss://connect.runlease.online $ runlease login
No uptime promise. What it allows and what it logs
Self-hosted relay
One small binary on one small VM, in your network, admitting only who you say.
- machines at once
- yours to set
- who can sign in
- your domain
- connection metadata
- stays with you
- price
- one small VM
Larger tiers
More machines at once on the public relay, for teams that would rather not run one. Not available yet.
- machines at once
- more
- status
- planned
Tell us what you would need in Discussions.
These limits are on the relay only. The machines run in your cloud account, on your bill, and Runlease does not meter them.
Open source
Read it. Run it. Add your cloud.
Runlease is Apache-2.0, about ten thousand lines of Go, with no service of ours in the path unless you choose one.
A cloud provider is four methods. GCP and AWS are done. Azure, Hetzner and DigitalOcean are open, and a provider is a good first contribution.
// pkg/provider/interface.go type CloudProvider interface { RequestSpot(ctx, spec) (*InstanceHandle, error) Terminate(ctx, id) error Status(ctx, id) (InstanceStatus, error) WaitUntilRunning(ctx, id) (*InstanceHandle, error) }