Provider docs used

Cloudflare Tunnel lets a connector make outbound-only connections from your server to Cloudflare. This tutorial follows Cloudflare's current Tunnel setup flow and adapts it for an Autohand Code runner: Create a tunnel.

Architecture

Autohand Code still runs on a Linux host or Docker host. Cloudflare Tunnel only handles remote access. The safest default is a local runner process bound to 127.0.0.1, with Cloudflare Access or a signed webhook in front of the public hostname.

ExposeUse when
HTTP webhookGitHub, Linear, Slack, or a Worker needs to trigger a job
SSHHumans need private terminal access through Cloudflare Access
Local dashboardYou build a small internal UI for queued Autohand Code jobs

Step 1: Run a local Autohand Code job trigger

Keep the process bound to localhost. The tunnel will publish it later.

// server.mjs
import { createServer } from "node:http";
import { spawn } from "node:child_process";

const repoDir = process.env.AUTOHAND_REPO_DIR;
const token = process.env.AUTOHAND_RUNNER_TOKEN;

createServer((req, res) => {
  if (req.method !== "POST" || req.headers.authorization !== `Bearer ${token}`) {
    res.writeHead(401);
    res.end("unauthorized");
    return;
  }

  const job = spawn("autohand", [
    "-p",
    "Review the latest repository state and summarize action items",
    "--restricted",
    "--output-format",
    "stream-json"
  ], { cwd: repoDir, env: process.env });

  job.stdout.on("data", chunk => process.stdout.write(chunk));
  job.stderr.on("data", chunk => process.stderr.write(chunk));
  res.writeHead(202);
  res.end("queued\n");
}).listen(8787, "127.0.0.1");

Step 2: Create the tunnel

You can create the tunnel in the Cloudflare dashboard or with cloudflared. The dashboard flow gives you an install command for your connector host.

cloudflared tunnel login
cloudflared tunnel create autohand-runner
cloudflared tunnel route dns autohand-runner autohand-runner.example.com

Step 3: Route the hostname to localhost

# ~/.cloudflared/config.yml
tunnel: autohand-runner
credentials-file: /home/autohand/.cloudflared/autohand-runner.json

ingress:
  - hostname: autohand-runner.example.com
    service: http://127.0.0.1:8787
  - service: http_status:404
cloudflared tunnel run autohand-runner

Step 4: Protect the route

For human access, put Cloudflare Access in front of the hostname. For machine access, validate a bearer token or webhook signature in the local runner before starting Autohand Code.

export AUTOHAND_RUNNER_TOKEN="$(openssl rand -hex 32)"
export AUTOHAND_REPO_DIR="$HOME/work/your-repo"
source ~/.autohand/env
node server.mjs

Step 5: Trigger a job

curl -X POST https://autohand-runner.example.com \
  -H "Authorization: Bearer $AUTOHAND_RUNNER_TOKEN"

Operations checklist

  • Keep the origin listener bound to 127.0.0.1.
  • Use Cloudflare Access for human-triggered jobs.
  • Use request signing or bearer tokens for machine-triggered jobs.
  • Run cloudflared under systemd so the tunnel restarts after reboot.
  • Log both tunnel health and Autohand Code job output.