nextv1.4.0
Guides

Remote access

Approve or reject a gate from a phone, over Tailscale or a tunnel, using the same password auth as the local board.

Reach the Kraft board from a phone or another machine by binding it off loopback and turning on password auth. You need a password, an allowed_hosts entry for the hostname you will type, and a non-loopback bind.

Before you start

Kraft binds 127.0.0.1 by default and skips auth for local clients. Any other bind makes Kraft require the password from every client, local ones included, and check browser Host headers against allowed_hosts.

Pick the narrowest bind that works:

  • Tailscale (recommended). Bind the machine's Tailscale address. Only devices on your tailnet can reach the board, and your LAN cannot.
  • Cloudflare Quick Tunnel. Put the board on the public internet. Use it only if you cannot use Tailscale.

Set a password

Set a password in Settings → Access while you are still on 127.0.0.1. kraft admin start refuses a non-loopback bind without one.

The port is 8765 unless you set port in access.yaml or pass --port. Use your port wherever this page says 8765.

Over Tailscale

  1. Find the machine's Tailscale address and name:
    tailscale ip -4        # e.g. 100.101.102.103
    tailscale status       # the first line names this machine
    
  2. In access.yaml, through Settings → Access or by hand, set bind to that address and add the machine's tailnet name, such as mybox.tailnet-name.ts.net, to allowed_hosts. Setting bind in the file, rather than passing --host, keeps the kraft CLI in your other shells pointed at the same address. Run kraft admin doctor to confirm the file parses.
  3. Stop any running server and start it again, so it reads the new bind. kraft admin restart would reuse the old bind, so it cannot switch it:
    kraft admin stop
    kraft admin start
    
  4. From a device on your tailnet, open http://mybox.tailnet-name.ts.net:8765/. Tailscale encrypts the traffic between your devices.

Start Tailscale before Kraft: the Tailscale address does not exist until Tailscale is up, and the bind fails without it.

Over a Cloudflare Quick Tunnel

A Quick Tunnel puts the board on the public internet. Anyone who finds the *.trycloudflare.com URL reaches the login page, and the password is the barrier. Kraft locks an address out for 15 minutes after 5 failed logins, but if the tunnel does not pass on the visitor's address, every visitor counts as one address and a stranger's guesses can lock you out too. See Login. Open only the tunnel's https:// URL, so the session cookie is marked Secure. The tunnel also needs --host 0.0.0.0, which listens on every interface, your LAN included. If your LAN is untrusted, block the port at your firewall for other interfaces.
  1. Stop any running server, then start it off loopback:
    kraft admin stop
    kraft admin start --host 0.0.0.0
    
  2. Run cloudflared tunnel --url http://localhost:8765. It prints a *.trycloudflare.com URL.
  3. Add that hostname to allowed_hosts in access.yaml, then run kraft admin restart, which keeps the non-loopback bind. The URL changes every time cloudflared starts, so repeat this step each time.

Verify

  1. From the phone or other machine, request the health endpoint, which needs no login:
    curl -s https://<your-tunnel-hostname>/api/health
    

    Over Tailscale, use http://mybox.tailnet-name.ts.net:8765/api/health. A JSON status confirms the request reaches Kraft.
  2. Open the same address without /api/health in a browser. You should see the login page. Log in with your password.
  3. If the browser shows a 403 with "unexpected Host", the hostname is missing from allowed_hosts. Add it and run kraft admin restart.

You get the real board, with the same auth. For the threat model, see Security. To call the API from off-machine, see Inbound triggers.

Copyright © 2026