Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

httpexec

Runs local commands over HTTP and describes itself with OpenAPI, so an API client — or an Arazzo workflow — can shell out without leaving the description.

There is no shell

Commands are executed directly, not interpreted. Shell syntax — redirection, pipes, globs, &&, variable expansion — is passed through as literal text:

{ "command": "echo", "args": ["hello > world.txt"] }
// → { "stdout": "hello > world.txt\n", "exitCode": 0 }, and no file

Ask for a shell when you want one:

{ "command": "sh", "args": ["-c", "echo hello > world.txt"] }
// → { "stdout": "", "exitCode": 0 }, and the file exists

Pass untrusted values as arguments rather than splicing them into the command, so they cannot escape it:

{ "command": "sh", "args": ["-c", "printf %s \"$1\" > out", "sh", "«value»"] }

Security

This server runs whatever it is told to run, and has no authentication. Anything that can reach the port has the privileges of the user running it.

It binds localhost on a random port by default. Do not change that unless you have put authentication in front of it. --hostname 0.0.0.0 publishes remote code execution to your network.

Usage

npx httpexec --port 8080
Flag Default
--port, -p 0 0 picks a free port.
--hostname, -h localhost See above before changing.
curl -X POST http://localhost:8080/ \
  -H 'content-type: application/json' \
  -d '{"command":"echo","args":["hello"]}'
{ "stdout": "hello\n", "stderr": "", "exitCode": 0 }

The OpenAPI description is served from /openapi.json, with servers set to the address it is actually reachable at.

A command that fails is still a 200

The response reports what happened; it is not itself the verdict. A command that ran and exited non-zero returns 200 with that exitCode. Only a malformed request body is a 400.

So check exitCode, not just the status:

successCriteria:
  - condition: $statusCode == 200
  - condition: $response.body#/exitCode == 0

Requirements

Node 22.18 or newer — the binary is TypeScript, run through Node's built-in type stripping.

License

MIT

About

Run local commands over HTTP, described by OpenAPI. Executes directly — there is no shell unless you ask for one.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages