shed

command module
v0.0.0-...-4022b72 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2026 License: MIT Imports: 14 Imported by: 0

README

Shed

Secure HTTP Execution Daemon

Overview

SHED is basically SSH - just over HTTPS.

SHED lets you securely execute any kernel command with an HTTP request (without a shell).

  • Direct Kernel Execution (no shell)
  • Bearer Token Auth (set in env var or arg)
  • Structured JSON I/O
  • Event Streaming
  • Lightweight (9.1 MB Go Binary)

WARNING: This project is early phase and experimental. It has not been battle-tested like SSH. I wanted to get the concept out there. But, if you like the idea of a stateless remote execution architecture, feel free to test it out.

Usage
Startup
# Start with auto-generated token
shed

# Start with custom token
shed -token mysecret

# Start on a specific port
shed -port 8080

# Disable auth (usually not recommended)
shed -no-auth

On startup, shed prints the generated token. Use it in requests:

  🏠 shed 0.1.0
  Secure HTTP Execution Daemon

  Listening on  0.0.0.0:7680
  Token         a1b2c3d4e5f6g7h8i9j10
Invocation

POST https://localhost:7680/exec

Headers

Authorization: Bearer <TOKEN>

Request Body

{
    "command":  ["ls", "-la", "/tmp"]
}

Response Body

{
  "stdout": "total 0\ndrwxrwxrwt 2 root root 40 Feb 23 ...\n",
  "stderr": "",
  "stdout_lines": ["total 0", "drwxrwxrwt 2 root root 40 Feb 23 ..."],
  "exit_code": 0,
  "duration": "3ms"
}

Installation

  1. Install Go
  • Mac: brew install go

  • Linux: sudo apt install golang-go

  • Windows: choco install golang

  1. Install Shed
  • go install github.com/oranda-io/shed@latest
  1. Add Go bins to your PATH:
  • export PATH=$PATH:$(go env GOPATH)/bin

Setup

Shed requires TLS and a bearer token by default. This creates a secure tunnel between the client and the server (much like SSH).

NOTE: You MAY run shed without a bearer token with -no-auth and without TLS with -insecure. Generally this is not recommended, but it can still be secure in some setups (e.g. private networking, ssl-proxy, etc).

TLS (self-signed)

TLS certs are required unless you use -insecure (not recommended).

TLS uses a public/private keypair. The certificate is what clients use to trust the server’s public key. With a self-signed cert, the server signs its own cert and clients must trust that exact cert.

openssl req -x509 -newkey rsa:4096 -nodes \
  -keyout key.pem -out cert.pem -days 365 \
  -subj "/CN=localhost"

shed -tls-cert cert.pem -tls-key key.pem

NOTE: Clients should ideally trust the certificate (or a local dev CA). Avoid disabling TLS verification. With a local dev CA, you create a CA once and sign server certs; clients trust the CA instead.

Authentication (bearer token)

By default, shed generates a random 256-bit token on startup and prints it to stdout. Pass it as a Bearer token:

Authorization: Bearer <token>

This can be overridden by passing a token with the -token argument.

NOTE: Token comparison uses constant-time comparison to prevent timing attacks.

Tests

go test ./...

API

GET /health

Health check. No auth required.

curl https://localhost:7680/health
{ "status": "ok", "version": "0.1.0", "uptime": "2m30s" }

NOTE: The /health endpoint is always unauthenticated.

POST /exec

Execute a command. Returns stdout, stderr, and exit code as JSON.

curl -H "Authorization: Bearer TOKEN" \
     -d '{"command": ["ls", "-la", "/tmp"]}' \
     https://localhost:7680/exec
{
  "stdout": "total 0\ndrwxrwxrwt 2 root root 40 Feb 23 ...\n",
  "stderr": "",
  "stdout_lines": ["total 0", "drwxrwxrwt 2 root root 40 Feb 23 ..."],
  "exit_code": 0,
  "duration": "3ms"
}

Request body:

Field Type Description
command string[] Command and arguments (required)
stdin string Data to pipe to stdin
env map<string,string> Additional environment variables
cwd string Working directory
timeout int Timeout in seconds (default: 30)
split_lines bool Include stdout_lines / stderr_lines

Commands are executed directly via execveno shell is involved. This is faster and more secure than piping through /bin/sh.

POST /exec/stream

Same as /exec but streams output in real-time via Server-Sent Events.

curl -H "Authorization: Bearer TOKEN" \
     -d '{"command": ["tail", "-f", "/var/log/syslog"]}' \
     https://localhost:7680/exec/stream
event: stdout
data: Feb 23 12:00:01 host CRON[1234]: ...

event: stdout
data: Feb 23 12:00:02 host sshd[5678]: ...

event: exit
data: 0

Flags

-port       Port to listen on (default: 7680)
-host       Host to bind to (default: 0.0.0.0)
-token      Auth token (env: SHED_TOKEN)
-tls-cert   Path to TLS certificate (env: SHED_TLS_CERT)
-tls-key    Path to TLS key (env: SHED_TLS_KEY)
-insecure   Allow plain HTTP without TLS (NOT recommended)
-no-auth    Disable authentication (NOT recommended)
-version    Print version and exit

Motivation

Why reinvent SSH?

SSH is stateful - but the modern web is stateless (largely). With SSH, your client must maintain a persistent connection, manage reconnects, and handle the connection lifecycle. With HTTP, the lifecycle is abstracted.

SSH is streaming - but the modern web uses a request / response model (largely). With SSH, your client must hold the stream open, buffer, and parse the result to identify hangs / failures. With HTTP, the response length is known prior to send and delivery is deterministic.

SSH is plaintext - but the modern web is JSON (largely). With SSH, your client must parse the response into a form your app logic can understand. With HTTP, you are given the complete response readily available as JSON with stdout, stderr, and exit code as structured JSON properties.

Why reinvent Docker Exec?

Docker Exec is great when you have access to the Docker Host. However, if you only have access to the container (e.g. GitHub Codespaces), then you need an alternative.

Is SHED really SSH?

SSH is a huge, complex program (183,000 lines of C) that supports things like X11 Forwarding (run graphical apps from a remote server), SFTP (file transfer), TCP tunneling (secure tunnel for TCP traffic), agent forwarding, Kerberos authentication, FIDO tokens, and tons of other features that have accumulated over 30 years.

But, SSH started simple - remote execution. So, SHED is SSH in its simpler, original form.

Is SHED really as secure as SSH?

SSH started in 1995, because Telnet sent passwords in plaintext. SSL already existed, but it was designed for the request-response model. SSH was designed for persistent terminal sessions.

Interactive terminal sessions were the norm at the time, but as the web has evolved, the client-server model became the standard.

TLS establishes the same encrypted tunnel, and TLS has become the transport encryption standard. With TLS, SHED provides the same transport security as SSH.

The main difference is auth: SSH uses per-user keypairs by default. Keypairs provide "non-transferable identity", because if someone steals the public key, you're still safe.

SHED uses a bearer token, which is functionally equivalent to password auth in SSH. Both can be considered secure over an encrypted connection. mTLS (per-user client certificates) is on the roadmap for full parity.

Doesn't HTTP also hold a stateful connection?

Both HTTP and SSH hold a stateful TCP connection.

The difference is, HTTP makes the TCP connection disposable and abstracts this implementation detail.

In SSH, the connection is first-class. Managing it (e.g. opening / closing) is the developer's responsibility.

You may find an SSH client that mimics this, abstracts the stateful connection and presents a stateless interface - but you'd need to do this for every client.

HTTP already solves this at the protocol level, so every HTTP client presents a stateless interface.

Is this AI garbage?

I encountered this problem as a real human, identified the solution, and came up with the name "SHE".

I used Claude Opus 4.6 to do deep research on alternatives. It found a few, but they were bundled with more complex services.

I used Claude and Codex to assist development / testing, but I reviewed the AI generated output carefully and use this solution in my Mobile IDE.

Claude also added a "D" to the name for "Daemon", and SHED is just cute, so that's what I went with.

What is the actual use-case?

For me, it was executing remote commands on a docker container to which I did not have host access. The obvious alternative is SSH, but creating stateful sessions just to run simple commands felt like overkill. I couldn't use Docker Exec, because I didn't have host access.

Why support SSE if SSH already supports streaming?

HTTP is the standard for the modern web. All tools natively support HTTP (and most support SSE). With SSH, you need to install an SSH client to stream command output.

HTTP handles connection state for you. If the connection drops, then HTTP handles it. In SSH, if the connection drops, then your app code generally handles that.

Antipitch

Don't use SHED if you need:

  • An interactive terminal (shed is one-way)
  • File Transfer (scp/sftp)
  • TCP Tunneling
  • Port Forwarding
  • Per-user OS-level isolation (at the moment, but this is on the roadmap)

License

MIT


Built by Oranda IO

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL