openclaw-cloudflare
v0.3.1
Published
Cloudflare integration plugin for OpenClaw (Tunnel, Access, and more)
Maintainers
Readme
openclaw-cloudflare
Cloudflare Access JWT verification plugin for OpenClaw. Verifies Cf-Access-Jwt-Assertion headers and sets identity headers for authenticated requests.
Assumes cloudflared is already running externally (Docker sidecar, systemd, Cloudflare's own connector, etc.).
Setup Guide
Step 1 — Install the plugin
openclaw plugins install openclaw-cloudflareStep 2 — Set up Cloudflare Access
- In the Cloudflare Zero Trust dashboard → Access > Applications → Add an application
- Choose Self-hosted
- Set the Application domain to the hostname pointing at your OpenClaw gateway (e.g.
openclaw.example.com) - Configure the identity providers and policies (who is allowed to access)
- Note your Team domain — visible at Settings > Custom Pages or in the URL:
https://<team>.cloudflareaccess.com
Step 3 — Configure the plugin
Add to your ~/.openclaw/openclaw.json:
{
"plugins": {
"entries": {
"openclaw-cloudflare": {
"config": {
"access": {
"teamDomain": "myteam"
}
}
}
}
}
}Step 4 — Start OpenClaw
openclaw gateway --forceThe plugin will verify Cloudflare Access JWTs on every incoming request and set x-openclaw-user-email for authenticated users.
Running cloudflared on your VM
This plugin only handles JWT verification — you need cloudflared running on the VM to route traffic through Cloudflare. Here's how to set it up as a persistent system service so it starts automatically.
1 — Create a tunnel in the Cloudflare dashboard
- Go to Cloudflare Zero Trust → Networks > Tunnels → Create a tunnel
- Choose Cloudflared, name it (e.g.
my-openclaw), click Save tunnel - Under Public Hostnames, add a hostname pointing to your OpenClaw gateway:
- Subdomain + domain: e.g.
openclaw.example.com - Service:
HTTP→localhost:18789(OpenClaw's default port)
- Subdomain + domain: e.g.
- Copy the tunnel token shown on the connector install page
2 — Install cloudflared
Debian/Ubuntu:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.debRHEL/Fedora:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm -o cloudflared.rpm
sudo rpm -i cloudflared.rpmARM64:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64 -o cloudflared
sudo install -m 755 cloudflared /usr/local/bin/cloudflaredmacOS:
brew install cloudflare/cloudflare/cloudflared3 — Install as a system service
Linux:
sudo cloudflared service install <your-tunnel-token>
sudo systemctl enable cloudflared
sudo systemctl start cloudflaredVerify it's running:
sudo systemctl status cloudflaredmacOS:
sudo cloudflared service install <your-tunnel-token>This registers a launchd plist that starts cloudflared automatically on boot.
Once the tunnel is active, all traffic arriving at your public hostname passes through Cloudflare Access — and this plugin verifies the resulting JWTs on each request.
OpenClaw gateway configuration
With cloudflared running on the same machine, the gateway only needs to be reachable on loopback. Configure ~/.openclaw/openclaw.json to bind locally, trust the local proxy, and delegate authentication to the identity headers this plugin sets:
{
"gateway": {
"bind": "loopback",
"trustedProxies": ["127.0.0.1"],
"auth": {
"mode": "trusted-proxy",
"trustedProxy": {
"userHeader": "x-openclaw-user-email"
}
}
}
}| Field | Value | Why |
|-------|-------|-----|
| gateway.bind | "loopback" | cloudflared connects to OpenClaw locally — no need to expose to LAN |
| gateway.trustedProxies | ["127.0.0.1"] | Only trust identity headers from cloudflared running on the same host |
| gateway.auth.mode | "trusted-proxy" | Delegate authentication to this plugin instead of using a password/token |
| gateway.auth.trustedProxy.userHeader | "x-openclaw-user-email" | This plugin sets this header after verifying the Cloudflare Access JWT |
How it works
When a request arrives with a Cf-Access-Jwt-Assertion header, the plugin:
- Verifies the JWT signature against Cloudflare's JWKS endpoint (
https://<teamDomain>.cloudflareaccess.com/cdn-cgi/access/certs) - Validates issuer, expiry, and audience (if
audienceis configured) - Sets
x-openclaw-user-emailandx-openclaw-auth-source: cloudflare-accessheaders for downstream use
Identity headers are always stripped from incoming requests before verification to prevent spoofing.
Supported algorithms: RS256, ES256 (via Node.js WebCrypto, no external deps). JWKS keys are cached for 10 minutes with automatic refresh on key rotation.
Configuration Reference
| Key | Type | Description |
|-----|------|-------------|
| access.teamDomain | string | Team domain for <team>.cloudflareaccess.com (required to enable) |
| access.audience | string | Optional AUD tag for stricter JWT validation |
