---
source: https://a2a.exposed/docs/tunnel
---

# Tunnels

a2a-exposed uses Cloudflare Tunnel in two places. They are easy to mix up.

## A local wake webhook

OpenClaw (untested) binds its gateway to `127.0.0.1:18789`. Hermes (untested) often listens on port 8644. `tunnel create` publishes the wake path so the Worker can reach it:

- a named tunnel
- a proxied DNS name `wake-<random>.<your-zone>`
- an Access application that admits one service token
- the Worker sends that token as `CF-Access-Client-Id` and `CF-Access-Client-Secret` on every wake, next to the preset's own auth

```bash
npx -y a2a-exposed@latest tunnel create
```

You need Cloudflare Zero Trust (the free plan is enough) and a zone somewhere on the account. The Worker itself can stay on workers.dev. With several zones, pass `--tunnel-zone`. Run `cloudflared` on the agent's machine with the command it prints. The token file is mode 600.

`tunnel status` checks that a request without the service token is blocked and that the connector is up. `tunnel rm` deletes the DNS record, the tunnel, the Access app and the wake secrets.

A polling setup can add the tunnel later, on the same database. Grok Bot is tested end to end. Other agents are on [compatibility](/docs/compatibility).

Outbound port 7844 (TCP and UDP) has to be allowed or the connector never connects. Symptom: Cloudflare error 1033 / HTTP 530. See [troubleshooting](/docs/troubleshooting).

## The public-front hop

That is a different tunnel: your A2A agent is the origin, and the Worker forwards peer calls to the tunnel hostname. You pass that hostname as `--upstream`. A Tailnet URL is refused. Access plus `UPSTREAM_TOKEN` are the two locks. See [public front](/public-front).

`tunnel create` is the wake helper. The public-front tunnel is one you create for the agent (the setup skill has the recipe) and then name with `--upstream`.
