Skip to main content
Every machine gets a public HTTPS certificate, and public certificates are listed in public logs. Crawlers read those logs and probe every hostname they find. Without protection, each probe would wake a machine that was sleeping just to answer a bot, and probes to a running machine would keep resetting its idle timer, so it would never go to sleep at all. Bot protection stops that. Before a request reaches the machine, boxd asks the visitor to pass a quick browser check. A real browser gets through in a second or two. A crawler doesn’t, so it never reaches your app.

Modes

Check which mode a machine has with boxd machine config get myapp bot-protection.

What visitors see

A visitor sees a short page with a Cloudflare Turnstile check: “One quick check” on a running machine, “This machine is asleep” on a sleeping one. Most of the time the check passes on its own without the visitor clicking anything. Once it passes, the page reloads and your app answers the request, after waking the machine if it was asleep. A passed check lasts 24 hours in that browser, for every machine on the same domain. Visiting another machine under boxd.sh in that time doesn’t ask again.

When the check applies

The check only runs when all of these are true:
  • The request is for the machine’s main address, myapp.boxd.sh or www.myapp.boxd.sh. If your org has a wildcard domain, myapp.vms.mysaas.com and www.myapp.vms.mysaas.com are covered too.
  • The machine’s mode covers its state: On in any state, Sleep only when it is in standby or hibernated.
  • The browser hasn’t passed the check in the last 24 hours.
These are never checked:
  • Subdomain proxies such as api.myapp.boxd.sh.
  • Custom domains pointed at a single machine.
  • Traffic over your org’s Tailscale or NetBird network. Only that network can reach it, so bot protection is off there whatever the machine’s setting.
  • SSH. It already requires your key, so it wakes machines as before.
The browser remembers a passed check with a boxd cookie. boxd removes that cookie before the request reaches your app, so your app never sees it.

Webhooks and API clients

Only a browser can pass the check. A webhook sender, API client, curl or uptime monitor that gets checked receives the check page with a 503 instead of your app. With On that happens on every request to the machine’s main address. With Sleep only it happens only while the machine is asleep, and the machine stays asleep. For a machine that something other than a browser must reach, send that traffic to a subdomain proxy (for example hooks.myapp.boxd.sh), which is never checked. Or choose Sleep only if those clients only need a running machine, or Off.

Set it for a machine

In the console, it’s the Bot protection menu on the machine’s Settings tab. Inside a machine, the in-machine CLI takes the same machine config set bot-protection <mode> command. The SDKs still accept true and false: true means On and false means Off. botProtection / bot_protection reads true for both On and Sleep only. A fork keeps the setting of its source machine, and a machine created from a snapshot keeps the setting the snapshot was taken with.

Org default

New machines start with your org’s default bot protection, if your org has one, and otherwise with the platform’s setting. Org admins set the default, and any member can read it. Setting the default also changes the existing machines you can manage: your own machines and the org’s shared machines. Machines with bot protection Off stay off, and other members’ private machines are left unchanged. To change only machines created from now on, use --new-only (in the SDKs, new_machines_only / newMachinesOnly).
The CLI prints what changed, for example changed 3 existing machines; 1 machine with bot protection off was left off. Clearing the default never changes an existing machine. In the console, it’s the Default bot protection section on the Organization page. The menu sets the default for new machines, and Apply to existing machines then applies it to the existing machines you can manage. Platform setting in the menu means the org has no default of its own. A fork or a machine created from a snapshot keeps its source’s setting, whatever the org default.