Skip to content

Stoffbergie/shell-over-edge

Repository files navigation

Shell Over Edge

Reach any shell from anywhere.

CI License: MIT

Shell Over Edge is a tiny Cloudflare Worker relay for temporary shell access when SSH, VPN, or inbound ports are not available. Start the generated agent on the target machine, copy the 8-character code, send commands over HTTPS, and get plain text output back.

Start

macOS/Linux:

curl -sS https://soe.stoff.dev | sh

Windows PowerShell:

irm https://soe.stoff.dev | iex

The target prints:

Session: 1234abcd (copied to clipboard)
Stop anytime: Ctrl+C

Commands

Raw command:

curl -sS -X POST https://soe.stoff.dev/1234abcd/send --data 'pwd'

Command with working directory:

curl -sS -X POST https://soe.stoff.dev/1234abcd/send \
  --data '{"body":"pwd","cwd":"/tmp"}'

Custom timeout:

curl -sS -X POST 'https://soe.stoff.dev/1234abcd/send?timeout=10' --data 'sleep 5'

Close the session:

curl -sS -X POST https://soe.stoff.dev/1234abcd/end

Default timeout is 30 seconds. timeout is URL-only. JSON command bodies support body and cwd.

API

Method Path Body Response
GET / empty POSIX agent by default, PowerShell for PowerShell clients
POST /<code>/send raw text or {"body":"pwd","cwd":"/tmp"} command output
POST /<code>/send?timeout=10 raw text or {"body":"pwd","cwd":"/tmp"} command output
POST /<code>/end empty ended

Architecture

sequenceDiagram
    participant Target as "Target shell"
    participant Worker as "Cloudflare Worker"
    participant Bridge as "Durable Object"
    participant Sender as "Sender"

    Target->>Worker: "GET / | sh"
    Worker-->>Target: "agent + code"
    Target->>Bridge: "GET /next"
    Sender->>Bridge: "POST /1234abcd/send"
    Bridge-->>Target: "command"
    Target->>Target: "run command"
    Target->>Bridge: "POST /result/:id"
    Bridge-->>Sender: "plain text output"
Loading

R2 stores session metadata and code lookups. A Durable Object owns each live command queue, pairs results with the right sender, and prevents parallel sends from mixing output.

Fresh Clone

Requirements:

  • Node.js 24 or newer
  • pnpm 11.5.2 via Corepack
  • Docker, only for pnpm run test:containers

Setup:

corepack enable
pnpm install --frozen-lockfile
pnpm run validate

pnpm run validate runs typecheck, test typecheck, lint, Vitest, repo audit, and a Cloudflare Worker dry-run bundle.

Local Development

pnpm run dev
curl -sS http://127.0.0.1:8787/

Extra checks:

pnpm run test:load
pnpm run test:containers
pnpm run benchmark
SOE_BASE_URL=https://soe.stoff.dev pnpm run smoke:prod

Tech Decisions

  • Cloudflare Worker keeps the public surface to one HTTPS edge deployment.
  • Durable Objects give each session one ordered queue and deterministic result pairing.
  • R2 stores only session metadata and code lookup records.
  • Generated POSIX and PowerShell agents avoid binary installs and release assets.
  • The 8-character code is the capability; /end closes it explicitly.

Limits

Item Limit
Session code 8 characters
Session TTL 2 hours
Command body 64 KB
Result body 1 MB
Command timeout 1-50 seconds

Automation instructions: llms.txt

Agent skill: skills/shell-over-edge/SKILL.md

About

Shell Over Edge: temporary shell and file access through Cloudflare Workers.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors