Supported release distributions include a pinned cloudflared executable next
to tunnel-client. Use this mode when a pre-provisioned, remotely managed
Cloudflare Tunnel token is available and tunnel-client should own the
companion process lifecycle.
The bundled companion is published for:
- Linux
amd64andarm64 - macOS
amd64andarm64 - Windows
amd64andarm64 - Docker images for Linux
amd64andarm64
Every target is built from the exact pinned upstream Go module source fetched
through an explicit proxy-only GOPROXY. The build verifies the pinned Go
module checksum, then compiles the module cache entry as the main module so
upstream replace directives remain effective. No supported path downloads
GitHub release assets, source tarballs, or direct VCS source. Windows arm64
uses the same source-build path as every other target.
Each platform archive contains:
tunnel-client(ortunnel-client.exe)cloudflared(orcloudflared.exe)cloudflared-manifest.jsonLICENSE
The combined all-platform archive keeps each pair under
bin/<os>_<arch>/, so the two executables stay adjacent.
Use a module proxy without a direct fallback:
GOPROXY=https://proxy.golang.org \
./scripts/build_cloudflared.sh \
--goos "$(go env GOOS)" \
--goarch "$(go env GOARCH)" \
--output "bin/$(go env GOOS)_$(go env GOARCH)/cloudflared"Replace the proxy URL with your organization's Go module proxy when one is
required. The script rejects GOPROXY=direct, GOPROXY=off, and proxy chains
that include a direct fallback.
Pass a reference instead of a literal token so the secret never lands in the shell history or process arguments:
export CLOUDFLARED_TOKEN='...'
tunnel-client run \
--cloudflared.token env:CLOUDFLARED_TOKEN \
--control-plane.tunnel-id tunnel_0123456789abcdef0123456789abcdef \
--mcp.server-url https://mcp.example.com/mcpFor file-backed secrets:
tunnel-client run \
--cloudflared.token file:/run/secrets/cloudflared-token \
--control-plane.tunnel-id tunnel_0123456789abcdef0123456789abcdef \
--mcp.server-url https://mcp.example.com/mcpCLOUDFLARED_TUNNEL_TOKEN is also accepted as a direct environment variable.
--cloudflared.path / CLOUDFLARED_PATH is an advanced source-build and test
override; supported release archives discover the adjacent bundled executable
without it.
For a logical tunnel created with managed Cloudflare provisioning, enable the authenticated runtime fetch instead of distributing a static token:
tunnel-client run \
--cloudflared.managed \
--control-plane.tunnel-id tunnel_0123456789abcdef0123456789abcdef \
--mcp.server-url https://mcp.example.com/mcpThe client uses CONTROL_PLANE_API_KEY and the configured organization context
to call GET /v1/tunnels/{tunnel_id}/cloudflare/runtime, validates the
returned metadata and token, and keeps the token in memory only. A configured
static --cloudflared.token or CLOUDFLARED_TUNNEL_TOKEN takes precedence
and bypasses this fetch.
Inspect the reviewed pin without starting a child process:
tunnel-client cloudflared versionIf an operator intentionally runs cloudflared without tunnel-client, print
a deterministic token-free config and store the tunnel token in a separate
secret file:
tunnel-client cloudflared config \
--token-file /run/secrets/cloudflared/token \
> /etc/cloudflared/config.yml
chmod 600 /run/secrets/cloudflared/token
TUNNEL_MANAGEMENT_DIAGNOSTICS=false \
cloudflared tunnel --config /etc/cloudflared/config.yml runThe generated YAML references only the token file path; it never reads or
embeds the token. It disables auto-update to preserve the reviewed pin, binds
metrics/readiness to loopback by default, keeps application logs at info and
transport logs at warn, uses automatic protocol/IP fallback, and sets
explicit retry and graceful-shutdown budgets. Override those defaults with
tunnel-client cloudflared config --help when the deployment requires a
different metrics listener or network policy. With the current reviewed pin,
run direct cloudflared processes with
TUNNEL_MANAGEMENT_DIAGNOSTICS=false; do not rely on
management-diagnostics: false in YAML.
When a static token is configured or managed fetch is enabled, tunnel-client run:
- fetches the managed runtime token first when requested and no static token is configured;
- launches bundled
cloudflared tunnel --no-autoupdate ... run; - passes the token only through the child
TUNNEL_TOKENenvironment variable, removes inheritedTUNNEL_MANAGEMENT_DIAGNOSTICSvalues, and forces oneTUNNEL_MANAGEMENT_DIAGNOSTICS=false; - waits up to
--cloudflared.ready-timeout(default30s) for the loopbackcloudflared/readyendpoint to report an active connection; - keeps
/readyzunavailable when the companion later loses readiness; and - stops the child on normal shutdown or exits nonzero when the child exits unexpectedly.
The diagnostics override removes remote /metrics and /debug/pprof
routes while preserving the local loopback readiness and metrics endpoints used
by tunnel-client.
The managed fetch bypasses raw HTTP body logging. Child output is redacted before it enters tunnel-client logs. The token is also redacted from support exports and effective config snapshots.
The pinned version is 2026.7.2, from the official
cloudflare/cloudflared release
at release commit 8679787525edc8575b2948a7c4a50b6292c6d426. The checked-in
pkg/cloudflared/manifest.json records
the exact Go pseudo-version, package path, module checksum, go.mod checksum,
build timestamp, and supported platforms. scripts/build_cloudflared.sh uses
go mod download through the configured proxy-only GOPROXY, verifies both
checksums, and refuses to build if module metadata drifts.
The tunnel-client maintainers own routine and emergency security updates: review each upstream release and security advisory, update the manifest, rebuild every supported distribution, and rerun the cloudflared lifecycle and package tests. Auto-update stays disabled so the runtime cannot silently drift away from the reviewed pin.