A Cloudflare Worker that provides an authenticated gateway to OpenClaw running in a private network. It uses Cloudflare Access for authentication and Workers VPC for secure connectivity.
- Cloudflare Access Authentication - Validates JWTs to ensure only authorized users can access the service
- VPC Service Binding - Securely connects to OpenClaw running in a private network via Cloudflare Tunnel
- OpenAI-compatible API - Exposes
/v1/chat/completionsendpoint for chat completions - WebSocket Proxy - Bridges real-time WebSocket connections between clients and OpenClaw
- SPA Routing - Serves the OpenClaw dashboard with proper client-side routing support
flowchart LR
User([User]) --> Access[Cloudflare Access]
Access --> Worker[Worker Gateway]
Worker --> Tunnel[Cloudflare Tunnel]
Tunnel --> OpenClaw[OpenClaw Gateway]
subgraph Cloudflare Edge
Access
Worker
end
subgraph Private Network
Tunnel
OpenClaw
end
- Cloudflare account with Workers enabled
- Node.js 18+
- Wrangler CLI
- OpenClaw running in a private network (see OpenClaw docs)
- Cloudflare Tunnel configured in your private network
-
Clone the repository and install dependencies:
git clone <repository-url> cd workers-openclaw-vpc npm install
-
Copy the example environment file and configure your secrets:
cp .env.example .env
-
Update
.envwith your Cloudflare Access policy AUD tag and team name:CF_ACCESS_AUD=your-access-application-aud-tag CF_ACCESS_TEAM_NAME=your-team-name.cloudflareaccess.com
-
Update
.envwith your OpenClaw gateway token:OPENCLAW_GATEWAY_TOKEN=your-gateway-token
-
Start the development server:
npm run dev
| Variable | Description | Required |
|---|---|---|
CF_ACCESS_AUD |
The Application Audience (AUD) tag from your Access application | Yes (secret) |
CF_ACCESS_TEAM_NAME |
Your Cloudflare Access team domain (e.g., your-team.cloudflareaccess.com) |
Yes (secret) |
OPENCLAW_GATEWAY_TOKEN |
The OpenClaw Gateway Token | Yes (secret) |
The wrangler.jsonc file contains the VPC Service binding configuration:
Install and configure cloudflared in your private network where OpenClaw is running:
cloudflared tunnel create openclaw-tunnel
cloudflared tunnel route dns openclaw-tunnel openclaw-internal.example.comConfigure the tunnel to point to your OpenClaw Gateway (default: http://localhost:18789). See the Tunnel documentation for detailed setup.
Create a VPC Service that connects to your OpenClaw instance:
npx wrangler vpc service create openclaw-service \
--type http \
--tunnel-id <your-tunnel-id> \
--hostname localhost \
--http-port 18789Save the returned Service ID for the next step. See VPC Services documentation for more options.
- Go to Cloudflare Zero Trust → Access controls → Applications
- Select Add an application → Self-hosted
- Configure the application domain to match your Worker's URL
- Create an Access policy to control who can access the application
- After saving, find the Application Audience (AUD) Tag in the application's overview page
See Cloudflare Access documentation for detailed setup.
-
Update
wrangler.jsoncwith your VPC Service ID -
Set the
CF_ACCESS_AUD,CF_ACCESS_TEAM_NAMEandOPENCLAW_GATEWAY_TOKENsecrets:npx wrangler secret put CF_ACCESS_AUD npx wrangler secret put CF_ACCESS_TEAM_NAME npx wrangler secret put OPENCLAW_GATEWAY_TOKEN
-
Deploy:
npm run deploy
| Route | Method | Auth | Description |
|---|---|---|---|
/v1/chat/completions |
POST | Yes | OpenAI-compatible Chat Completions API. Make sure you enable API for your Gateway. |
/tools/invoke |
POST | Yes | Tools invocation API |
/ |
GET | Yes | WebSocket proxy; redirects HTTP to /app |
/app/* |
GET | Yes | SPA routes (OpenClaw dashboard) |
/assets/* |
GET | Yes | Static assets |
/chat.html |
GET | Yes | Demo chat interface (see below) |
A simple chat interface is included at /chat.html for testing the /v1/chat/completions API endpoint. This is a standalone HTML file that demonstrates:
- Streaming chat completions with Server-Sent Events (SSE)
- Conversation history management
- Basic error handling
Note: The demo uses a hardcoded model name (openclaw:main). If you're using a different model, edit public/chat.html and update the model constant on lines 207 and 286.
npm run dev # Start development server
npm run cf-typegen # Generate TypeScript types
npm run deploy # Deploy to productionContributions are welcome! Please feel free to submit a Pull Request.
MIT
{ "vpc_services": [ { "binding": "VPC_SERVICE", "service_id": "<your-vpc-service-id>", "remote": true } ] }