Mac worker Cloudflare Tunnel

Mac worker Cloudflare Tunnel

BRI-397. This is a dedicated tunnel named brioso-m5, separate from the VPS
tunnel. The existing worker bearer authenticates requests; Cloudflare Access
is not used. Only /jobs and /jobs/{call_id} reach the workers.

The checked in configuration prepares both beta and production with the same
route restrictions and authentication. Production uses its own hostname and
localhost worker port. Applying the private tunnel configuration and updating
the live gateway row are separate rollout steps; this preparation does not
change live routing. The diagram shows the prepared production route beside
the last verified live SSH route.

Hostname Origin Runtime
m5-beta.usebrioso.com http://127.0.0.1:7312 home-m5-beta
m5-prod.usebrioso.com http://127.0.0.1:7311 home-m5-production

deploy/cloudflared/m5.yml.example is the shareable template. On the Mac,
PM2 starts brioso-m5-cloudflared with
--config ~/.config/brioso/m5/cloudflared.yml; that private file is the
configuration the running connector reads. It has the same ingress rules
as the template, plus the real tunnel UUID and credentials path. Recreate it
from the template on a new Mac, or copy only changed ingress entries into
an existing private file so its UUID and credentials stay intact. Validate
and restart the connector after either change.

An ingress hostname matches the address in an incoming web request. It does
not identify or allowlist the computer sending that request. Cloudflare routes
matching /jobs and /jobs/{call_id} requests to the corresponding local
worker; the final rule returns 404 for other paths. Both names are public DNS
names, subject to Cloudflare’s edge rules. The workers require their own
HOME_WAKE_TOKEN bearer for the job routes, including requests forwarded from
the Mac’s loopback interface. This setup does not use Cloudflare Access or a
source computer allowlist.

Prepared routes and recorded rollout status

M5 worker routing and rollout status

Editable Excalidraw source.
Recorded on 2026-10-17: beta completed a 15 second M5 generation and its
FLAC was downloaded and decoded. Missing, wrong, and opposite environment
bearers were rejected; status requests bypassed cache.

The production HTTPS canary passed authentication and generated audio, but
its R2 upload failed TLS validation. The Mac received a certificate for
core1.netops.test instead of the R2 host. The job was cancelled, the
production gateway restored to http://127.0.0.1:17311/jobs, and production
tunnel ingress disabled. Production M5 end to end verification has not passed.
The same Mac egress problem may affect new beta uploads. Keep TLS validation
enabled and retain SSH until production passes its own acceptance test.

Baseline and authentication

Read each environment’s authenticated GET /internal/admin/gpu-gateway.
Save the response outside Git with mode 0600. Record the matching runtime
row and its runtimes[].version, plus the full fallback chain. Do not save
bearer values or PM2 environment dumps in the rollout evidence.

The verified 2026-10-17 baseline uses HOME_WAKE_TOKEN in both live rows,
version 4. Beta points to http://127.0.0.1:17312/jobs; production points to
http://127.0.0.1:17311/jobs. Each chain contains its M5 runtime then
modal-espetro. Re-read before activation; these are historical values.

Both private worker files under ~/.config/brioso/m5/ must contain
BRIOSO_WAKE_REQUIRE_TOKEN=1 and distinct, nonempty HOME_WAKE_TOKEN values.
Verify each against the backend variable named by its live push.tokenEnv.
The addon gateway examples use a different token reference; do not apply
them over the live rows. The worker launcher sources the private env file
after PM2 sets its environment, so check that file as well as the profile.

Keep worker bindings at 127.0.0.1, the model at 127.0.0.1:7309, and
both workers on the same BRIOSO_ADMISSION_LOCK_PATH. Before restarting a
worker, verify it is idle via its local /health endpoint.

Provision and start

Install cloudflared through mise. Use an authenticated Cloudflare operator
session for usebrioso.com, then create a new locally managed tunnel:

mise exec -- cloudflared tunnel login
mise exec -- cloudflared tunnel create brioso-m5

Copy deploy/cloudflared/m5.yml.example to
~/.config/brioso/m5/cloudflared.yml. Replace the tunnel UUID and absolute
credential path with those emitted by creation. Keep the configuration and
credential JSON mode 0600 and their directory mode 0700. Do not reuse the
VPS tunnel token. The Mac connector metrics bind only to 127.0.0.1:7313.
The example includes both environments. For the existing tunnel, retain its
UUID and credential path and add the production ingress from the example.

mise exec -- cloudflared tunnel --config "$HOME/.config/brioso/m5/cloudflared.yml" ingress validate
mise exec -- cloudflared tunnel --config "$HOME/.config/brioso/m5/cloudflared.yml" ingress rule https://m5-beta.usebrioso.com/jobs
mise exec -- cloudflared tunnel --config "$HOME/.config/brioso/m5/cloudflared.yml" ingress rule https://m5-prod.usebrioso.com/jobs
mise exec -- cloudflared tunnel --config "$HOME/.config/brioso/m5/cloudflared.yml" ingress rule https://m5-prod.usebrioso.com/health

Expect the matching worker origin for each /jobs URL and http_status:404
for /health. Check existing DNS records before creating missing proxied
CNAMEs; reuse records already pointing to this tunnel:

mise exec -- cloudflared tunnel route dns brioso-m5 m5-beta.usebrioso.com
mise exec -- cloudflared tunnel route dns brioso-m5 m5-prod.usebrioso.com

In the zone’s Cache Rules, add a rule with expression
http.host in {"m5-beta.usebrioso.com" "m5-prod.usebrioso.com"} and Cache
eligibility Bypass cache. Place it after any overlapping cache rules.
Preserve other zone rules and check that no Worker route overrides caching.
This Cloudflare setting is required separately from tunnel ingress.

Start just the new connector alongside SSH:

mise exec -- node_modules/.bin/pm2 start deploy/pm2/ecosystem.m5-cloudflared.config.cjs
mise exec -- node_modules/.bin/pm2 save

For an existing connector, restart only brioso-m5-cloudflared after
validating the private configuration and confirming both workers are idle.
Use mise for PM2 startup so cloudflared is on its process PATH. Confirm the
existing PM2 login startup service restores the connector after reboot.
The profile disables automatic binary updates; upgrade through mise.

Verify and activate

For the active HTTPS hostname, test both POST /jobs and GET /jobs/test-call.
Missing, incorrect, and opposite environment bearer values must return 401.
The matching bearer with an empty JSON POST must return 422 without starting
work; a nonexistent call GET returns 200 with the worker’s unknown state.
Read credentials in memory and never place them in shell arguments or logs.

Verify /, /health, /wake, /v1/models, /docs, /jobs/, and nested
paths return 404. Repeat authenticated status requests and inspect cache
headers; they must never be served as a cache HIT. Check the configured rule
as well, since a cache MISS alone does not establish bypass.

For beta, copy the captured runtime object and change only push.url to
https://m5-beta.usebrioso.com/jobs. PUT that object to
/internal/admin/gpu-gateway/runtime/home-m5-beta with If-Match set to the
fresh row version. Authenticate with the existing admin credential. On 412,
re-read and review the concurrent change; never retry without the guard.
Re-read the complete gateway and confirm the only configuration difference
is that URL. Preserve tokenEnv, runtime IDs, and fallback chains.

For production, apply the same URL-only update with
https://m5-prod.usebrioso.com/jobs and
/internal/admin/gpu-gateway/runtime/home-m5-production, using its own fresh
row version and existing token reference. The production gateway example
contains the prepared HTTPS URL; do not import its whole registry or replace
the live credential reference. Repeat the authentication and route checks
above with the production bearer.

Submit one beta generation through the application. Correlate the accepted
call, HTTPS status polling, M5 runner, terminal paid state, and downloaded
audio. A Modal completion does not pass this M5 check. Production uses the
same setup, but a full generation and download remain unverified until a
production acceptance run is possible. Configuration validation and HTTP
checks do not establish that R2 uploads succeed. Production MCP may be
disabled; do not enable it for this rollout.

With both workers idle, restart brioso-m5-cloudflared and repeat beta HTTPS
checks. For a future fallback check, stop the connector briefly during a
controlled beta submission;
verify that the existing chain completes through Modal, then restart the
connector and verify both hosts recover. Avoid this interruption while
either M5 worker has an accepted call. Verify both workers still share the
same admission lock. Record job IDs and output checks; revoke test keys.

Only after production also moves to HTTPS and passes its checks:

mise exec -- node_modules/.bin/pm2 stop brioso-m5-tunnel
mise exec -- node_modules/.bin/pm2 save

Keep the SSH profile for manual rollback. Starting the entire home profile
again also starts SSH; select individual processes for routine restarts.

Rollback

Start brioso-m5-tunnel and verify both VPS loopback health endpoints.
Read the current gateway rows and restore each saved original push URL with
its current If-Match version. Preserve concurrent unrelated changes.
Verify the restored URLs, token references, and chains, then stop
brioso-m5-cloudflared and save PM2 state. Keep mandatory bearer auth.
Never register SSH as an extra runtime, which could duplicate dispatch.

References: ingress configuration,
cache settings.