Cloudflare Hub
Cloudflare is the public edge layer for all OpenClaw webhook traffic. It provides the canonical tunnel (webhook.reri.co), WAF rules protecting inbound endpoints, and DNS management for the reri.co zone. Read this hub before changing any tunnel config, WAF rule, or DNS record. Owner: Henry Hill / Claude Code. Governed by CLAUDE.md §MANDATORY: Webhook Endpoint Governance and FUNNEL-REGISTRY.
Quick reference
| Field | Value |
|---|---|
| Vendor | Cloudflare |
| URL | https://dash.cloudflare.com |
| KB doc | API |
| Auth method | API Token (Bearer) |
| Auth credential | op://Aurora/cloudflare/api-token |
| Cred-proxy port | n/a (until B1-B6 ratified) |
| Webhook port | n/a (Cloudflare is the tunnel — not a local handler) |
| Webhook handler | n/a |
| Webhook dedup table | processed_webhook_events (24h TTL) — enforced at handler level |
| Tunnel path | all /webhook/* and /sms, /voice paths via webhook.reri.co |
| Outbound API base | https://api.cloudflare.com/client/v4 |
| Rate limits | 1,200 req / 5 min per token (default); 30,000 URLs per cache purge |
| Rate-limit action | 429 → exponential backoff (3 retries), Discord ops alert |
| Cost | Free tier / Pro 200/mo |
| Backup/recovery | Tunnel ID 849121e5-0db6-4076-b591-268783143377 — Tailscale Funnel is fallback |
| Discord alert channel | ops |
| Drift cadence | Weekly — security-audit-funnel.timer (Mon 06:00 America/Los_Angeles) |
| Status | production |
Tunnel: Tailscale Funnel + Cloudflare Tunnel for public webhooks
OpenClaw uses Cloudflare Tunnel (reri-api, ID 849121e5-0db6-4076-b591-268783143377) as the canonical path for all inbound webhooks. The tunnel terminates at the VPS and routes to local handler ports per FUNNEL-REGISTRY. Tailscale Funnel (srv1347501.tailb025a7.ts.net) is maintained as an instant rollback path only — providers are no longer registered there post-Phase 8.
Tunnel architecture
Internet → webhook.reri.co (CF Tunnel v19)
/webhook/hubspot → :18790 hubspot-handler.js
/webhook/openphone → :18792 quo-handler-enhanced.js
/webhook/salesmessage → :18793 salesmessage-handler-v4-complete.js
/sms, /voice → :18797 twilio-voice-handler.js
/webhook/docusign → :18790 hubspot-handler.js (DocuSign routes)
/webhook/gmail-push → :18801 gmail-push-handler.js
<catch-all> → HTTP 404 (hard reject)
Fallback path: srv1347501.tailb025a7.ts.net — same ports, unadvertised. Tailscale path strips some prefixes; dual-URL Twilio verifier handles the canonical CF path but rollback-via-Tailscale is untested for Twilio HMAC verification.
Governance rules
- Every public endpoint MUST exist in FUNNEL-REGISTRY BEFORE going live. Adding a path to the tunnel without a registry entry is a governance violation per
CLAUDE.md §MANDATORY: Webhook Endpoint Governance. - Four non-negotiable requirements per endpoint: (a) IP filter or signature verification, (b) dedup via
processed_webhook_events, (c) non-blockingwebhook_audit_logwrite with/tmp/webhook-audit-fallback.jsonlfallback, (d) handler port documented in registry. - Removals: wait for 15+ minutes of parity events in
webhook_audit_logbefore removing old route. - After any tunnel/funnel change: run
node workspace/scripts/security-audit-funnel.js --dry-runand verify clean.
SalesMsg token note
SalesMsg uses a query-param token (?secret=...), NOT HMAC. The KB once stated otherwise — the KB was wrong. Never switch SalesMsg to HMAC without verifying via live event headers. See feedback_salesmsg_api_first and FUNNEL-REGISTRY webhooks/salesmessage rows.
WAF + Security: DocuSign IP allowlist 90-day rotation; FUNNEL-REGISTRY.md governance; security-audit-funnel.timer
WAF rules
The Cloudflare Pro WAF is bound to webhook.reri.co. Custom rules enforce:
- HubSpot WAF header filter — validates the
X-HubSpot-Signature-V1header presence before traffic reaches the handler. - DocuSign IP allowlist — Cloudflare custom rule allows only DocuSign’s published IP ranges. Source: WEBHOOK-IP-RANGES.
DocuSign IP allowlist — 90-day rotation
The DocuSign WAF IP allowlist has no auto-refresh. It must be manually re-saved to the Cloudflare WAF rule from the current DocuSign IP range source approximately every 90 days. The security-audit-funnel.timer flags staleness if the allowlist has not been refreshed.
Rotation process:
- Read current ranges from WEBHOOK-IP-RANGES
## DocuSignsection. - Open Cloudflare Dashboard → WAF → Custom Rules →
docusign-ip-allowlist. - Update the
ip.src in {<ranges>}expression. - Save and verify with
node workspace/scripts/security-audit-funnel.js --dry-run. - Insert an
infra_config_changesrow withchange_type='waf_rule_update'per CHOKEPOINT-2.
Weekly governance audit — security-audit-funnel.timer
security-audit-funnel.timer runs every Monday at 06:00 America/Los_Angeles and alerts Discord #ops on:
| Check | Alert condition |
|---|---|
| Unregistered live paths | path live in tunnel but not in FUNNEL-REGISTRY |
| Missing approved paths | path in registry but not live |
| Signature failure rate | >5% of inbound events failing sig check |
| Zero-event endpoints | endpoint active but no events in last 7 days |
| Stale WAF rules | DocuSign IP allowlist older than 90 days |
If this alert fires, open FUNNEL-REGISTRY + fix drift before proceeding with other work.
Run manually: node workspace/scripts/security-audit-funnel.js --dry-run
Credential governance
No Cloudflare API tokens are stored in workspace files. The production token lives exclusively at op://Aurora/cloudflare/api-token. See 1password for op:// access patterns via the op CLI.
DNS: subdomain routing
All DNS for reri.co is managed through Cloudflare. Key records:
| Record | Type | Target | Proxied | Purpose |
|---|---|---|---|---|
webhook.reri.co | CNAME | 849121e5-0db6-4076-b591-268783143377.cfargotunnel.com | Yes | Canonical webhook tunnel |
reri.co | A/CNAME | RERI Website Supabase project | Yes | Public website |
Proxied vs DNS-only: when proxied: true, Cloudflare masks the VPS origin IP and applies CDN + WAF. DNS-only records (proxied: false) return raw IP — never use DNS-only for webhook subdomains.
TTL when proxied: always 1 (automatic). Custom TTLs only apply to DNS-only records.
DNS changes require infra_config_changes row per CHOKEPOINT-2 before going live. After any DNS change, allow up to 5 minutes for Cloudflare propagation (proxied records update immediately; DNS-only TTLs vary).
API: use Cloudflare API PATCH /zones/{zone_id}/dns_records/{record_id} for targeted updates. Avoid PUT (full replace) unless intentional.
Components
workspace/scripts/security-audit-funnel.js— weekly tunnel/WAF/registry drift auditworkspace/FUNNEL-REGISTRY.md— authoritative registry of all approved public endpointsworkspace/knowledge-base/cloudflare/API.md— Cloudflare REST API v4 reference (verified 2026-03-04)workspace/knowledge-base/security/WEBHOOK-IP-RANGES.md— DocuSign IP ranges for WAF allowlist- Cloudflare Tunnel daemon — runs as VPS process, connects to Cloudflare edge
security-audit-funnel.timer— systemd timer (Mon 06:00 LA) for weekly audit
How it’s used
- Trigger: inbound webhook event arrives at provider (HubSpot deal update, Twilio SMS, etc.)
- Flow: Provider → Cloudflare edge → WAF rules evaluate → Cloudflare Tunnel → local handler port → signature verify →
processed_webhook_eventsdedup →webhook_audit_log→ agent dispatch - Agents involved: _summary, _summary, _summary — all consume inbound webhook events downstream
- Failure mode: tunnel daemon crashes → all inbound webhooks fail silently. Recovery:
systemctl --user restart cloudflared(or equivalent). Fallback: Tailscale Funnel (unadvertised, instant rollback — update provider webhook URLs first). - Success criteria:
webhook_audit_logrows flowing for all registered providers within 1h of startup;security-audit-funnel.js --dry-runexits clean.
Cross-links
Agents that touch this
- _summary — primary builder, Discord ops alert consumer
- _summary — infrastructure oversight
- _summary — consumes HubSpot + OpenPhone webhook events
Skills that invoke this
- acquisitions-outreach — inbound trigger via /webhook/hubspot
- acquisitions-followup — inbound trigger via /webhook/salesmessage, /webhook/openphone
Plans that govern this
- openclaw-fragmentation-fix-2026-05-01 — Phase 9 tunnel migration history
- openclaw-obsidian-vault-2026-05-02 — vault sync references tunnel config
Feedback rules
- feedback_cloudflare_plan_before_execute — no tunnel changes without a plan
- feedback_tailscale_serve_strict_approval — Tailscale Funnel changes require Henry approval
- feedback_action_gate_violation_repeated — service restarts require explicit auth
- feedback_no_plaintext_creds — G-NO-PLAINTEXT-CREDS; all tokens via op://Aurora/
KB / source docs
- API — Cloudflare REST API v4 (last verified 2026-03-04)
- WEBHOOK-IP-RANGES — DocuSign + other provider IP ranges
System maps
- infrastructure — full infra topology
- integrations — webhook flow diagram
Related: Infra/compute cluster
This hub is part of the Infra/compute cluster alongside:
- hetzner — VPS host, compute substrate
- aws — EC2 Mac Ultra, S3, InvestorLift scraping
- github —
traewayrer/openclaw-vault(vault security posture — github → cloudflare cross-ref: vault sync commits flow from VPS through GitHub; Cloudflare tunnel protects VPS)
Webhook/tunnel cluster anchor: cloudflare is the anchor for hubspot, salesmsg, twilio, openphone-quo, discord.
Open issues / TODOs
- DocuSign WAF allowlist last rotation date unknown — verify against WEBHOOK-IP-RANGES at next session
/webhook/docusignisapproved-inactive(0 DocuSign Connect configs live) — needs DocuSign Connect configuration before going active/webhook/gmail-pushisapproved-pending-harden— sig verify and dedup not confirmed- Tailscale Funnel → Twilio HMAC rollback path is untested — verify before next incident
Recent activity
- 2026-05-03: hub created (W1-S7 sub-agent)
- 2026-04-21: FUNNEL-REGISTRY.md created; all 4 providers migrated to
webhook.reri.covia CF Tunnel v19 - 2026-04-21:
security-audit-funnel.timergovernance established