# Cloudflare dashboard — click-paths

The dashboard is the only surface for operations the CLI cannot perform: signing in, adding a site, editing an apex CNAME, deleting a tunnel after its replicas are stopped, and switching accounts. The agent does not drive the dashboard — it relays the numbered steps below to the operator, who runs them in their own browser.

Anchor on the dashboard's text labels, not pixel positions. Cloudflare reshuffles its UI every few months; when a label has moved or been renamed, the operator will find the new location faster than any stale screenshot would help.

**Never fabricate a navigation path.** Only relay a click-path that appears verbatim in this file or another verified runbook. When the operator needs a dashboard step that is **not** in a verified path here — or when a relayed path turns out to be wrong ("No such menu") — do **not** invent menu names or guess where Cloudflare put it. Ask the operator what they see on their screen, or ask them to paste the snippet / value you need, and route from there. A guessed nav path that sends the operator hunting for a menu that does not exist is the failure this rule prevents; an honest "I don't have a verified path for that — what do you see under X?" is correct.

---

## Sign in and confirm which account

1. Open https://dash.cloudflare.com in a browser.
2. If a sign-in page appears, sign in with the email that owns your Cloudflare account.
3. Look at the top-left corner of the dashboard, next to the orange Cloudflare cloud icon. The account name shown there is the account the laptop will also be bound to when you run `tunnel login` from the device. Confirm this is the right account before continuing.

---

## Switch between Cloudflare accounts

1. Click the account name in the top-left corner (next to the orange cloud).
2. A dropdown appears listing every account your sign-in has access to.
3. Click the account you want to switch into. The dashboard reloads on that account.
4. Verify the new account name now shows in the top-left before running any CLI command.

---

## Add a domain to a Cloudflare account

1. With the correct account active (top-left), click **Websites** in the left-hand sidebar.
2. Click the **Add a site** button.
3. Enter the bare domain (e.g. `example.com`, not `www.example.com`) and click **Continue**.
4. Cloudflare scans the domain's existing DNS records and presents them for review. Confirm any records you want preserved — website (`A`), email (`MX`), and DNS verification (`TXT`) records are common.
5. Cloudflare gives you two nameservers (e.g. `adam.ns.cloudflare.com`, `eve.ns.cloudflare.com`). Copy them.
6. Open your domain registrar's control panel in a separate browser tab and replace the registrar's nameservers with the two from Cloudflare.
7. Return to Cloudflare and click **Check nameservers**. The zone shows **Pending** until propagation completes (minutes to 24 hours); it moves to **Active** once Cloudflare's edge sees the new nameservers on the domain.

---

## Verify a zone's nameservers are correct

1. Click **Websites** in the sidebar, then click the domain you want to check.
2. The zone's status appears at the top — **Active** means Cloudflare serves DNS for this zone; **Pending** means the registrar has not yet switched nameservers to Cloudflare's.
3. For a deeper check, click **DNS** in the sidebar, then **Records**. At the top of the records list, Cloudflare shows the two assigned nameservers for this zone. Those are the exact values the registrar must set at the domain level.

---

## Authorise a new tunnel (pick the right zone)

This page opens automatically when `cloudflared tunnel login` runs on the device.

1. The "Authorize Cloudflare Tunnel" page shows every zone on the currently-active account.
2. Click the zone you want the tunnel to be able to route DNS for.
3. Click **Authorize**. The browser closes or shows "You can close this page."
4. Return to the terminal — `cloudflared` prints `You have successfully logged in.` once the cert lands.

If the account shown in the top-left is not the one that owns the zone you need, click the account-name dropdown first (see "Switch between Cloudflare accounts") and re-authorise from the right account.

---

## Edit an apex CNAME (bare-domain hostname)

Apex hostnames — a record at the zone root, e.g. `maxy.chat` rather than `www.maxy.chat` — cannot be routed by `cloudflared tunnel route dns` because standard DNS forbids CNAMEs at zone apex. Cloudflare's workaround (CNAME flattening) is only exposed via the dashboard. When the agent prints an `ACTION REQUIRED` block for an apex (per `references/manual-setup.md` § Step 4), these are the steps:

1. Click **Websites** in the sidebar, then click the apex zone (e.g. `maxy.chat`).
2. Click **DNS** in the sidebar, then **Records**.
3. If a record already exists at `@` (zone apex): click **Edit** on that record, set **Type** to `CNAME`, **Content** to the tunnel target (e.g. `<UUID>.cfargotunnel.com`), leave **Proxy status** as **Proxied** (orange cloud), and click **Save**.
4. If no record exists at `@`: click **Add record**, set **Type** to `CNAME`, **Name** to `@`, **Content** to the tunnel target, **Proxy status** to **Proxied**, and click **Save**.

Cloudflare applies CNAME flattening automatically for apex CNAMEs under a CF-managed zone — no further flag needed.

---

## Delete a tunnel after stopping its replicas

`cloudflared tunnel delete` refuses when any connector process is still running against the tunnel. For token-mode tunnels (created by a central operator, run on a device with `--token`), the connector is not managed by the local `cloudflared` CLI.

1. On the device, run `pkill -f 'cloudflared.*tunnel run --token'` to terminate the local token-mode connector. See `references/reset-guide.md` for the exact incantation.
2. Open the dashboard and navigate to **Zero Trust** → **Networks** → **Tunnels**.
3. Find the tunnel by name. The **Status** column should now say **Inactive** or **Degraded** — the connector count dropped to zero because Step 1 killed it.
4. Click the tunnel's row, then click the **...** menu on the far right, then **Delete**.
5. Confirm the deletion in the dialog.

If **Status** still shows **Healthy** with connectors > 0, another device is also running the tunnel — track down and stop those connectors first.

---

## List CNAME records in a zone

1. Click **Websites** in the sidebar, then click the zone.
2. Click **DNS** in the sidebar, then **Records**.
3. Filter the records list by **Type** = `CNAME`. Every CNAME in the zone shows — Name, Content (the target), Proxy status, TTL.

Use this when you need to audit which hostnames are pointing at which `<UUID>.cfargotunnel.com` target, or to find stray records left by a prior tunnel setup that should be deleted.

---

## Delete a stray CNAME

1. List the CNAMEs in the zone (see above).
2. Find the record you want to remove. Confirm its target is the stale tunnel — do not delete a record pointing at a live tunnel.
3. Click **Edit** on the record, then **Delete**, then confirm in the dialog.

`references/reset-guide.md` names the scenarios where this cleanup is load-bearing (post-reset stray records, account-switch residue).

---

## Author an Access policy for SSH or SMB

When the agent adds an SSH or SMB ingress hostname (per `references/manual-setup.md`),
the Access policy must exist before off-LAN clients can reach the Pi. There are two
paths: the agent can author it via the Cloudflare API with the reused Access-scoped
token (`<brand>-access`, minted once if absent — see `references/api.md` § Access and
§ Provisioning and reusing a stable per-scope token), or the operator can author it by hand in the
dashboard with the click-path below. `cloudflared` CLI has no Access-application create
subcommand, so the dashboard path is the manual alternative to the API.

1. Click **Zero Trust** in the sidebar.
2. Click **Access** → **Applications**.
3. Click **Add an application**, then **Self-hosted**.
4. Set **Application name** to the hostname (e.g. `ssh.maxy.bot`).
5. Set **Application domain** to the same hostname. **Subdomain** is the
   first DNS label (`ssh`), **Domain** is the registered parent zone
   (`maxy.bot`), **Path** stays blank.
6. Click **Next** through the identity/CORS pages (defaults are fine
   for a single-operator setup).
7. On the **Add policies** page, click **Add a policy**.
8. **Policy name:** "Operator allow". **Action:** `Allow`.
9. Under **Configure rules** → **Include**, add a rule:
   **Selector** = `Emails`, **Value** = the operator's email (the same
   one named in the `ACTION REQUIRED` block).
10. Click **Save** to land the policy, then **Add application** to land
    the application.

Repeat for the SMB hostname if the script printed both. Identity list
gates both routes; the same emails apply.

**Verify:** From an off-LAN machine run
`cloudflared access login https://ssh.<brand>.<rootdomain>`. Cloudflare
prompts for the operator email, sends a one-time PIN, and returns to a
success page. Then `cloudflared access ssh --hostname ssh.<brand>.<rootdomain>`
opens an SSH prompt to the Pi.

---

## Create a URL Rewrite Rule

A URL Rewrite Rule silently rewrites the path the origin server receives without changing the URL the visitor sees in their browser. Use this when you want a custom domain root (e.g. `getmaxy.com/`) to serve a path that lives elsewhere on the origin (e.g. `/sites/getmaxy/`) without redirecting the visitor.

This is **not** the same as a Page Rule redirect. Page Rules issue a visible 301/302 to the browser; a Rewrite Rule changes only what the origin receives, transparently.

1. Click **Websites** in the sidebar, then click the zone.
2. Click **Rules** in the left-hand sidebar, then **Overview**.
3. Click **Create rule**, then select **URL Rewrite Rule**.
   Alternatively, click **Create from template** and choose **"Rewrite path of moved section"** for a pre-filled starting point.
4. Enter a descriptive **Rule name** (e.g. `getmaxy apex → marketing site`).
5. Under **If incoming requests match**, select **Custom filter expression** and enter the expression. For a match on bare domain and www:
   ```
   (http.host eq "example.com") or (http.host eq "www.example.com")
   ```
6. Under **Then**, set **Path** → **Rewrite to** → **Dynamic** and enter the expression:
   ```
   concat("/sites/mysite", http.request.uri.path)
   ```
   Leave **Query string** on **Preserve** (unchanged).
7. Click **Deploy**.

No server restart is needed. Verify with `curl -s https://<domain>/ | head` — the response should be the site's HTML, not the agent SPA `<div id="root">`.

**When the zone cert misroutes:** if `cloudflared tunnel route dns` is run for a hostname in a zone the cert was not authorised for at `tunnel login`, it silently creates a record in the wrong zone (appends the cert's zone as a suffix). Check the emitted record name in the command output; if it has an unexpected suffix, delete the stray record via `DNS → Records` and create the CNAME manually in the correct zone instead.

---

## Web Analytics — registration is here, but collection is a beacon in the HTML

Cloudflare Web Analytics is configured in the dashboard, but registering a site there does **not** start collection — the beacon must be present in the served HTML. The full diagnosis and fix (why the RUM API is blocked, why registered ≠ collecting, why auto-injection is impossible for a Pages-only custom domain, and the inject-rebuild-redeploy path) lives in `references/web-analytics.md`. Read it before answering any "0 visitors / no analytics" question.

Because Cloudflare moves this area and the exact menu path varies by account, do not guess the click-path to the Web Analytics page. Ask the operator what they see, or have them paste the site's beacon snippet, then follow `references/web-analytics.md`.

---

## Where tunnels live in the dashboard (as of 2026-04)

Tunnels are under **Zero Trust** → **Networks** → **Tunnels**. This is not in the top-level sidebar — it is under the Zero Trust sub-dashboard, which itself appears in the main sidebar. Cloudflare has moved this location in the past. If **Networks** → **Tunnels** is not visible under Zero Trust, the label has likely been renamed; look for "Tunnels" under Networks or Access.
