SSH & WebAssembly
SSH
SSH executes commands on remote machines directly over SSH. No agent required — connects with password or key authentication. UPLOAD and DOWNLOAD transfer files between your namespace and the remote machine.
Single command — password auth
SSH "root" AT "123.45.67.89" PASSWORD "mypassword" ENTER `ls /var/www` SET ?result
AFTER EMIT ?result("stdout")
Key-based authentication
SSH "deploy" AT "123.45.67.89" KEY "/root/keys/id_rsa" ENTER `git pull` SET ?result
AFTER EMIT ?result("stdout")
Custom port
SSH "admin" AT "123.45.67.89" ON "2222" PASSWORD "mypassword" ENTER `uptime` SET ?result
AFTER EMIT ?result("stdout")
Multi-command block
Multiple commands are written as newlines inside the backtick block. They run sequentially in the same session.
SSH "deploy" AT "123.45.67.89" KEY "/root/keys/id_rsa" ENTER `
cd /var/www/myapp
git pull
npm install --production
pm2 restart all
` SET ?result
AFTER EMIT ?result("stdout")
File transfer — namespace to remote
SSH "deploy" AT "123.45.67.89" KEY "/root/keys/id_rsa" UPLOAD "/root/config.json" TO "/var/www/myapp/config.json"
File transfer — remote to namespace
SSH "root" AT "123.45.67.89" PASSWORD "mypassword" DOWNLOAD "/var/log/app.log" INTO "/mounted/logs/app.log" SET ?path
AFTER EMIT ?path
Checking exit code
SSH "root" AT "123.45.67.89" PASSWORD "mypassword" ENTER `systemctl is-active nginx` SET ?r
AFTER IF ?r("exit_code") IS EQUAL TO 0
OPEN
EMIT "nginx is running"
CLOSE
OR
OPEN
EMIT "nginx is down"
CLOSE
Return value
SSH returns an object for every ENTER call.
| Field | Type | Description |
|---|---|---|
stdout | string | Standard output from the command |
stderr | string | Standard error from the command |
exit_code | number | Process exit code — 0 is success |
| Verb | Description |
|---|---|
SSH "user" AT "host" PASSWORD "pass" ENTER `cmd` SET ?r | Single command via password auth. Default port 22. |
SSH "user" AT "host" KEY "/root/key" ENTER `cmd` SET ?r | Single command via key auth. |
SSH "user" AT "host" ON "port" [AUTH] ENTER `cmd` SET ?r | Custom port. |
SSH "user" AT "host" [AUTH] UPLOAD "/root/src" TO "/remote/dst" | Copy file from namespace to remote machine. |
SSH "user" AT "host" [AUTH] DOWNLOAD "/remote/src" INTO "/mounted/dst" SET ?path | Copy file from remote machine into namespace. |
WebAssembly
The WEBASSEMBLY verb runs code in another language or a compiled binary, fully sandboxed from the rest of the server. Only your namespace’s /root and /mounted are visible inside the sandbox — nothing else on the server exists from its perspective.
GRANT
Before entering a sandbox, you choose exactly which OcaltQL variables it can see. WEBASSEMBLY GRANT exposes a variable under an alias. Nothing is shared unless explicitly granted.
STRING "hello" SET ?var
AFTER WEBASSEMBLY GRANT ?var AS "varalias"
Multiple grants can be chained before a single ENTER block — each one adds another variable to the sandbox’s oql object.
STRING "Ocalt" SET ?name
AFTER NUMBER 5 SET ?count
AFTER WEBASSEMBLY GRANT ?name AS "name"
AFTER WEBASSEMBLY GRANT ?count AS "count"
TYPE & ENTER
WEBASSEMBLY TYPE "language" ENTER \`code\` SET ?result runs the code in the specified language, inside the sandbox, with access to anything granted beforehand. Whatever the code outputs becomes the result.
STRING "hello" SET ?var
AFTER WEBASSEMBLY GRANT ?var AS "varalias"
AFTER WEBASSEMBLY TYPE "php" ENTER `
echo $oql['varalias'];
` SET ?result
AFTER EMIT ?result
Supported Types
Granted variables are available inside the sandbox as an oql object, in the idiomatic form for each language.
| TYPE | Access grants as |
|---|---|
| php | $oql['alias'] |
| python | oql['alias'] |
| node | oql.alias |
| ruby | oql['alias'] |
| perl | $oql{'alias'} |
| java | oql.get("alias") |
| bash | $OQL_alias (env var) |
| wasm | passed as WASI env vars OQL_alias |
Compiled WebAssembly
When TYPE is wasm, ENTER takes a namespace path to a compiled .wasm file instead of inline source.
WEBASSEMBLY TYPE "wasm" ENTER "/root/modules/compute.wasm" SET ?result
AFTER EMIT ?result
Sandbox isolation
Every WEBASSEMBLY execution runs in an isolated filesystem view. The code being executed can only ever see two paths: /root and /mounted — both mapped directly to your own namespace. The real server filesystem, other users’ namespaces, and Ocalt’s internal infrastructure are completely invisible. There is no path traversal, no symlink escape, and no shared state with the host.