Skip to content

Guides

Create a mesh

jalth init creates a new mesh in your Cloudflare account. It takes about two minutes and orchestrates six Cloudflare products behind a single interactive flow.

  • Cloudflare account (free tier is fine)
  • Cloudflare API token with the recommended permissions
  • WARP client installed (jalth doctor reports missing prerequisites)

Optional: A domain on Cloudflare — required only for jalth serve with custom hostnames. Pass --domain myteam.com during init or set it later with jalth domain set.

Terminal window
jalth init

With a custom domain (enables jalth serve immediately):

Terminal window
jalth init --domain myteam.com

For headless servers and CI (no browser SSO):

Terminal window
jalth init --unattended
  1. Validate credentials — Verifies API token permissions and auto-detects your admin email and Zero Trust team name.

  2. Deploy Registry Worker — Creates D1 database, runs migrations, deploys the Worker with your API token as a secret.

  3. Configure Zero Trust — Email OTP IdP, Access Groups (jalth-members, jalth-admins, jalth-operators), enrollment policies, WARP device profile, SSH CA.

  4. Enroll this device — Writes WARP MDM config, registers device, assigns CGNAT IP.

  5. Save config — Writes ~/.jalth/config.json with registry URL and device token.

The API token is bound to the Worker as a secret during deploy. It is never stored in D1 or client config. Future jalth init runs need the token again; upgrades do not.

PermissionScopeLevelUsed for
User DetailsUserReadAuto-detect admin email
Zero TrustAccountEditDevices, Gateway DNS, connectivity
Access: Organizations, IdPs, GroupsAccountEditEnrollment policies, Access Groups
Access: Apps and PoliciesAccountEditWARP enrollment app, service apps
Access: SSH AuditingAccountEditGateway SSH CA
Access: Service TokensAccountEditHeadless init + auth-key joins
Cloudflare TunnelAccountEditjalth serve tunnel lifecycle
Cloudflare DEXAccountReadFleet status enrichment
Workers ScriptsAccountEditDeploy Worker, bind secrets
D1AccountEditMesh database
DNSZoneEditExposed service hostnames

Add people and headless servers:

Terminal window
jalth role set sarah@team.com member
jalth group add members --domain myteam.com
jalth auth-key create --name homelab --reusable

Share the join URL:

jalth join https://jalth.myteam.com

Coexistence with existing Cloudflare setup

Section titled “Coexistence with existing Cloudflare setup”

jalth reuses existing resources when safe:

  • WARP enrollment — Works alongside same-org enrollment; different org requires leaving first.
  • Device profile — Creates jalth-mesh-routing with its own split tunnel; default profile untouched.
  • Resources — All jalth resources are prefixed jalth-*. Existing resources are never modified.
  • Destroy — Only deletes resources jalth created; pre-existing resources are left intact.

If init fails midway, run jalth init again. Step 3 reconciles control-plane state — reuses what exists, creates what’s missing.