Cloudflare publication and gateway
This document describes the implemented Cloudflare integration and its verification procedure. It does not assert that the current provider resources or public URL are live; use the saved deployment receipt and cloudflare-status output for that claim.
Request model
The public Worker serves https://tokn.bepc.cc. It serves the landing page, explorer UI, documentation, acquisition interface and versioned release archives from Workers Static Assets. Its dynamic routes are:
POST /rpc -> allowlisted reads and explicitly signed raw broadcasts
GET /health -> native-chain health
GET /metrics -> aggregate response counts
POST /claims -> bounded persistent manual-review request, no payment
GET /claims/health -> intake readiness, no queue contentsThese requests pass through the Worker, Access Service Auth and the tokn-origin.bepc.cc Tunnel. The ingress terminates at the isolated web-gateway service. RPC and health use the existing node; counters and claims use separate local SQLite stores. The tunnel Compose service runs cloudflared. Explorer data is loaded through /rpc; there is no /explorer/api/* endpoint. Static pages can remain available during an origin outage, while dynamic failures return controlled errors. This design has one origin and does not provide origin redundancy.
The Worker also supports the corresponding read-only HEAD and API preflight requests. It rejects unknown/private paths, sends only Content-Type and Accept upstream, and adds the Access service-token headers. Client authorization, cookies and IP headers are not forwarded. RPC bodies are limited to 64 KiB and claim bodies to 8 KiB. Upstream calls have a 15-second timeout and no automatic retries: a lost POST response can follow a successful transaction broadcast or stored claim. Claim retries must preserve their request ID and exact body. Upstream responses must be bounded JSON; redirects and other content types become 503 responses.
No account or CAPTCHA is required for public pages, RPC reads or the human claim form when its persistent intake is enabled. RPC supports signed broadcasts, so it is not an exclusively read-only service. Reading or connecting does not sign or pay. A claim is a review request, never grant approval. The curator separately verifies the documented 100 TOKN useful-help or 500 TOKN ten-block node evidence and authorizes any payment. The gateway mounts no signing keys and fetches no submitted evidence URL. Public queue listing and private counter ingestion are rejected. Unavailable review/testnet interfaces remain omitted until their separate service gates pass.
Local commands
The project justfile provides optional shortcuts. Direct maintainer commands use uv:
uv run --no-project --no-config --no-cache python scripts/cloudflare.py plan
uv run --no-project --no-config --no-cache python scripts/cloudflare.py build
uv run --no-project --no-config --no-cache python scripts/cloudflare.py publish
uv run --no-project --no-config --no-cache python scripts/cloudflare.py statusThe pinned Wrangler installation under web/ uses Node/npm. All Python runs through uv, including the pinned uv container used by the gateway; no global just or separate Python installation is required for participants. Docker Compose runs the connector and gateway. Prepare private metrics storage and follow claim storage preparation before enabling the claims overlay. Preserve existing database contents and ownership during restarts.
docker compose -f compose.cloudflare.yaml -f compose.claims.yaml up -d --no-deps web-gateway tunnelplan is offline. Initial infrastructure provisioning is a separate infrastructure action that verifies the configured zone and token and creates or reuses only the named resources with an ownership receipt. Routine releases preserve that infrastructure. build requires a matching immutable release and verified live origin; it rejects secret material. publish builds and atomically deploys the Worker and assets. status reports the Tunnel status, connector count, version and service-token expiry without printing credentials. An explicit release build must precede publication; a private --claims-fixture candidate must never be promoted as live.
The commands write private receipts under the project state/secrets directories. Keep those files mode 600. The Cloudflare API token, Tunnel token, Access client secret, account ID, and zone ID must never enter public assets, logs, git, or this document.
Worker publication details
The publisher generates dist/cloudflare/wrangler.json with selective run_worker_first routes for the public HTML sections, release archives and API paths. This ensures page/archive responses reach the counter hook; other assets retain asset-first serving. The Worker accepts exact /rpc, /health and /metrics routes, plus bounded /claims submission and /claims/health when their persistent origin is enabled. Dedicated testnet routes retain their own prefix. The publisher enables them only when the same build includes a pilot that passed the current service, configuration and peer-roster gates; otherwise every testnet path returns 404 without contacting the origin. Public counter ingestion and claim listings are rejected. It attaches the custom domain TOKN_DOMAIN, sets TOKN_ORIGIN_URL to the HTTPS origin hostname, enables observability with 10% head sampling, and disables invocation-log payload output. Generated public files are allowlisted and scanned for credential material before deployment.
Static asset delivery is free and unlimited under the current Workers Static Assets billing model, with no additional asset-storage charge. Workers Free currently allows 100,000 Worker requests/day, 10 ms CPU per invocation, 128 MB memory, 50 subrequests per invocation, and 25 MiB per static asset. This Worker buffers bounded RPC/claim bodies and bounded JSON responses; the 64 KiB application limit is stricter than Cloudflare's 100 MB Free request-body limit. A paid Workers plan is not required for the current feature set; do not enable paid usage without review.
Access and Tunnel boundary
The named remote Tunnel is tokn-origin.bepc.cc, separate from the Worker hostname. Its ingress points only to http://web-gateway:8080. cloudflared runs from the pinned Docker image in compose.cloudflare.yaml with the Tunnel token mounted read-only. The connector needs outbound connectivity; no creator, treasury, validator, wallet, or onion keys are copied into it.
The Worker receives ACCESS_CLIENT_ID and ACCESS_CLIENT_SECRET through Wrangler secrets. Access uses a Service Auth policy containing exactly the origin service token. The service token currently has an annual lifetime in the infrastructure request (8760h). Rotate it by creating the replacement, publishing the Worker, testing /health and /rpc, then revoking the old token. Cloudflare displays a client secret only at creation; never recover or print it from logs.
Verification and recovery
- Run
just cloudflare-planand confirm the intended public and origin hostnames without provider calls. - Confirm the configured zone is the expected Cloudflare zone before any write. Run
just cloudflare-infrastructureonce and retain its private receipt. - Start the reviewed
web-gatewayandtunnelservices with the claims overlay when enabled. Confirm local health and database persistence across a gateway restart without adding synthetic records to the real queue. - Run
just cloudflare-publish, thenjust cloudflare-status. Check the saved Worker publication result, Tunnel status, connector count, and service-token expiry. - Verify static
/,/get-tokn/,/explorer/,/docs/,/manifest.jsonand the downloaded archive hash over public HTTPS. Verify/health,/claims/health,/metricsand a harmless RPC read separately. Reject malformed claim data to test the public POST route without creating a real queue record. Record the vantage point; a same-host HTTPS check is not an independent operator test. - Test the failure boundary by stopping only the origin stack and confirming static files remain available while
/healthand/rpcreturn 503; restart it and repeat the live checks. - For rollback, redeploy the last known-good immutable release and restore only the matching private provider receipt after inspecting current DNS, Access, and Tunnel state. Do not delete volumes, regenerate identities, or overwrite unrelated DNS records.
Official references
- Workers Static Assets billing and limitations
- Workers platform limits
- Static Assets configuration and `run_worker_first`
- Worker Custom Domains
- Cloudflare Tunnel overview
- Tunnel API: create a named Tunnel
- Access service tokens
- Access Service Auth policies
- Workers pricing
- Workers Logs
Aggregate response counters use only the protected gateway and its project-local state/metrics mount with private container UID/GID 65534 ownership. The public and Tor gateways leave TOKN_METRICS_DB unset. Claims use their separate state/claims mount and the same private ownership; only the explicit overlay enables it. See counter scope and privacy.
Page/archive middleware consumes the existing free Worker request allowance; static asset bypass would skip these counters. No paid plan is enabled. Routing follows Cloudflare Worker-first documentation.