irons is a CLI tool for spinning up egress-secured cloud VMs (sandboxes) designed for use with AI agents. It lets you create isolated, SSH-accessible environments with fine-grained control over outbound network traffic β so you can give an agent a real machine to work in without giving it unfettered internet access.
We're currently in early access. We're keeping the number of teams small so every sandbox boots fast and stays fast.
We'll get you API keys and have you spinning up secure sandboxes in 15 minutes.
Each sandbox is a cloud VM provisioned through the Iron.sh API. Egress rules are enforced at the network level, meaning you can allowlist only the domains an agent needs to reach (e.g. a package registry, an internal API) and block everything else. Rules can also be set to warn mode, which logs violations without blocking them β useful for auditing before locking things down.
The quickest way to install irons on macOS or Linux. Downloads the latest release, validates its SHA-256 checksum, and installs the binary to an appropriate location on your $PATH:
curl -fsSL https://raw.githubusercontent.com/ironsh/irons/main/install.sh | bashPre-built binaries for macOS and Linux are available on the GitHub Releases page.
Requires Go 1.24+.
git clone https://github.com/ironsh/irons.git
cd irons
just build # or: go build -o bin/irons .Add bin/irons to your $PATH, or install directly:
go install github.com/ironsh/irons@latestAll commands require an API key. Set it via the IRONS_API_KEY environment variable (recommended) or the --api-key flag:
export IRONS_API_KEY=your-api-keyBy default, irons talks to https://elrond.ironcd.com. Override this with IRONS_API_URL or --api-url.
# Create a sandbox and wait until it's ready
irons create my-agent-sandbox
# SSH in
irons ssh my-agent-sandbox
# When done, tear it down
irons destroy my-agent-sandboxProvision a new sandbox.
irons create NAME [flags]
| Flag | Default | Description |
|---|---|---|
--key, -k |
~/.ssh/id_rsa.pub |
Path to an SSH public key |
--async |
Return immediately without waiting for the sandbox to be ready |
Examples:
# Basic creation
irons create my-sandbox
# Custom SSH key
irons create my-sandbox --key ~/.ssh/agent.pub
# Fire-and-forget (don't wait for ready)
irons create --async my-sandboxStart a sandbox that was previously stopped.
irons start NAME [--async]
Waits for the sandbox to reach the ready state unless --async is passed.
Stop a running sandbox. The sandbox can be restarted later.
irons stop NAME [--async]
Waits for the sandbox to reach the stopped state unless --async is passed.
Permanently destroy a sandbox and clean up all associated resources.
irons destroy NAME [--force]
| Flag | Description |
|---|---|
--force |
Automatically stop the sandbox first if it is currently running |
Examples:
irons destroy my-sandbox
irons destroy --force my-sandbox # stop first if runningShow the current status and metadata of a sandbox.
irons status NAME
Displays the sandbox name, lifecycle state, creation and update timestamps, and any metadata. Includes a visual indicator:
| Indicator | Meaning |
|---|---|
| π’ | Running / ready |
| π‘ | Starting up |
| π | Stopped |
| π΄ | Error |
Open an interactive SSH session in a sandbox (or print the SSH command).
irons ssh NAME [flags]
| Flag | Description |
|---|---|
--command, -c |
Print the SSH command instead of executing it |
--strict-hostkeys |
Enable strict host key checking (disabled by default) |
Examples:
# Interactive session
irons ssh my-sandbox
# Print the connection command for use in scripts or other tools
irons ssh --command my-sandboxForward a port from a sandbox to your local machine via SSH tunneling.
irons forward NAME [flags]
| Flag | Default | Description |
|---|---|---|
--remote-port, -r |
(required) | Remote port on the sandbox to forward |
--local-port, -l |
same as --remote-port |
Local port to listen on |
--command, -c |
Print the SSH command instead of executing it | |
--strict-hostkeys |
Enable strict host key checking (disabled by default) |
Examples:
# Forward sandbox port 3000 to localhost:3000
irons forward my-sandbox --remote-port 3000
# Forward sandbox port 3000 to a different local port
irons forward my-sandbox --remote-port 3000 --local-port 8080
# Print the SSH command instead of running it
irons forward my-sandbox --remote-port 3000 --commandManage outbound network rules for sandboxes.
Allowlist a domain so that HTTPS traffic to it is permitted.
irons egress allow api.github.com
irons egress allow crates.ioExplicitly block outbound traffic to a domain.
irons egress deny registry.npmjs.org
irons egress deny ads.example.comList all current allow and deny rules for the account.
irons egress listGet or set the enforcement mode for egress rules.
# Get current mode
irons egress mode
# Block traffic that doesn't match an allow rule
irons egress mode deny
# Log violations without blocking (useful for auditing)
irons egress mode warn| Mode | Behaviour |
|---|---|
deny |
Outbound traffic to non-allowlisted domains is blocked |
warn |
Violations are logged but traffic is not blocked |
Inspect the history of outbound network connection attempts for a sandbox.
Print the egress audit log for a sandbox β every outbound connection attempt, whether it was allowed or denied, and which mode was in effect at the time.
irons audit egress NAME [--follow]
| Flag | Description |
|---|---|
--follow, -f |
Continuously poll for new events (like tail -f) |
Each line of output contains four space-separated fields:
TIMESTAMP VERDICT HOST (mode: MODE)
| Field | Description |
|---|---|
TIMESTAMP |
RFC 3339 timestamp (local time) of the connection attempt |
VERDICT |
ALLOWED if the connection was permitted, DENIED if it was blocked |
HOST |
The destination hostname |
MODE |
The egress mode active at the time: warn (log only) or deny (block) |
Example output:
2026-02-19T16:41:54-07:00 ALLOWED changelogs.ubuntu.com (mode: warn)
2026-02-19T16:42:00-07:00 ALLOWED example.com (mode: warn)
2026-02-19T16:42:09-07:00 ALLOWED example2.com (mode: warn)
2026-02-19T16:42:26-07:00 DENIED example2.com (mode: deny)Examples:
# Print the full egress audit log for a sandbox
irons audit egress my-sandbox
# Tail the log and print new events as they arrive
irons audit egress my-sandbox --followTip: Run
irons audit egress --followwhile your egress mode is set towarnto observe which domains your agent is reaching before switching todeny. This makes it easy to build a precise allowlist without trial and error.
These flags are available on every command:
| Flag | Env var | Default | Description |
|---|---|---|---|
--api-key |
IRONS_API_KEY |
API key for authentication | |
--api-url |
IRONS_API_URL |
https://elrond.ironcd.com |
API endpoint URL |
-
Provision a sandbox with the SSH key your agent will use:
irons create agent-run-42 --key ~/.ssh/agent.pub -
Lock down egress to only what the agent should reach:
irons egress mode deny irons egress allow api.openai.com irons egress allow pypi.org
-
Connect your agent using the SSH command output:
irons ssh --command agent-run-42
-
Monitor the sandbox if needed:
irons status agent-run-42
-
Tear down when the run is complete:
irons destroy --force agent-run-42
just build # build to bin/irons
just test # run tests
just run # go run . (pass args after --)
just clean # remove build artifacts
just deps # tidy go.mod / go.sumSee LICENSE.