Provider docs used

Cloudflare Workers can validate HTTP requests at the edge and forward to your runner. Store sensitive values as Worker secrets, not plaintext Wrangler variables. Keep the current docs open: Workers docs and Workers secrets.

Architecture

The Worker does not run the Autohand Code CLI. It validates inbound requests, checks tokens or signatures, and forwards approved jobs to a runner endpoint. The runner can be exposed through Cloudflare Tunnel, a private origin, or Cloudflare Containers.

Step 1: Create the Worker

npm create cloudflare@latest autohand-trigger
cd autohand-trigger

Step 2: Add the trigger code

export default {
  async fetch(request, env) {
    if (request.method !== "POST") {
      return new Response("method not allowed", { status: 405 });
    }

    const auth = request.headers.get("authorization");
    if (auth !== `Bearer ${env.PUBLIC_TRIGGER_TOKEN}`) {
      return new Response("unauthorized", { status: 401 });
    }

    const body = await request.text();
    const runnerResponse = await fetch(env.RUNNER_URL, {
      method: "POST",
      headers: {
        authorization: `Bearer ${env.RUNNER_BACKEND_TOKEN}`,
        "content-type": "application/json"
      },
      body
    });

    return new Response(await runnerResponse.text(), {
      status: runnerResponse.status
    });
  }
};

Step 3: Store secrets

Cloudflare secrets are encrypted bindings attached to a Worker and available through env in the fetch handler. Use them for tokens and origin URLs that should not appear in source control.

wrangler secret put PUBLIC_TRIGGER_TOKEN
wrangler secret put RUNNER_BACKEND_TOKEN
wrangler secret put RUNNER_URL

For local development, put development-only values in .dev.vars and keep that file out of git.

Step 4: Deploy and trigger

wrangler deploy

curl -X POST https://autohand-trigger.example.workers.dev \
  -H "Authorization: Bearer $PUBLIC_TRIGGER_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"repo":"your-org/your-repo","task":"review latest changes"}'

Step 5: Make the runner task-aware

Have the origin runner parse the JSON body and map allowed tasks to fixed Autohand Code prompts. Avoid letting arbitrary webhook payloads become raw shell commands.

const prompts = {
  review: "Review the latest changes and summarize action items",
  docs: "Update documentation for the latest CLI behavior"
};

const selected = prompts[payload.task] || prompts.review;
spawn("autohand", ["-p", selected, "--restricted", "--output-format", "stream-json"], {
  cwd: repoDir,
  env: process.env
});

Operations checklist

  • Use Worker secrets for trigger and backend tokens.
  • Validate request method, content type, signature, and allowed task names.
  • Do not expose model provider keys to the Worker unless the Worker itself calls the model provider.
  • Forward only normalized, allowlisted jobs to the runner.
  • Use Cloudflare logs or a Tail Worker for debugging webhook traffic.