By · Founder, Stacktree · Last updated
blog · privacy

Private-by-default HTML hosting is the new normal.

Public-by-default static hosting was a fine baseline when humans hand-wrote each page. Now agents emit HTML at human-commit rates, and most of it embeds real data. The baseline has to flip — and the new normal looks specific.

Get started free

What does 'private-by-default HTML hosting' mean in 2026?

A hosting model where the URL is unguessable by default, the file isn't publicly indexable, and viewer authentication is opt-in per link rather than opt-in per workspace. The unguessable URL is the floor; password gates, email-domain gates, and end-to-end encryption layer on top. The model exists because AI-emitted HTML routinely contains real data — API responses, customer rows, prompt context — and the old public-by-default contract no longer fits that risk surface.

The trigger: HTML-volume from agents

The shift is downstream of one observable change: AI agents now produce HTML the way humans produce commits. A single Claude Code or Codex session can emit ten or twenty self-contained HTML files — perf reports, spec writeups, custom inspectors, status pages, single-file tools. Multiply by a team and a week and you get hundreds of files no one was going to hand-edit but everyone needs to share.

Each of those files tends to bake in something real. The perf report has request volumes. The status page has customer names. The inspector has API responses pasted in for context. None of it is intentionally sensitive, all of it is at-rest sensitive in aggregate.

Why the old defaults don't work

Three traditional defaults break:

  • Public-by-default static hosts (GitHub Pages, Netlify free tiers) treat privacy as a paid bolt-on. The URL is on the open web; the only protection is "nobody knows it exists yet."
  • Workspace-SSO models (Confluence, intranet, paid SaaS) gate by org membership. Fine for long-lived team docs; clumsy for one-off artifacts you'd send to one person who isn't in your IdP.
  • Inbox attachments + Slack uploads are private but unfindable. The artifact effectively dies when the message scrolls off.

What "private-by-default" actually requires

Four properties, in order of how often they're needed:

  1. Unguessable URL. Sufficient entropy that the link can't be enumerated. Usable as the credential for the most common case (link in Slack to a small audience).
  2. Per-link password. A second factor for cases where the URL might be forwarded.
  3. Email-domain gate with magic-link verification. Strong protection because the gate survives forwarding — the recipient has to prove they own an email at the gated domain.
  4. End-to-end encryption (optional). AES-GCM in the browser, decryption key in the URL fragment, ciphertext on the server. Eliminates the host as a trust party for the few workloads where you can't accept it as one.

The same artifact rarely needs all four. The point is having them as a menu rather than a roadmap.

The CSP corollary

Privacy isn't only about who reads the page; it's also about what the page can do once opened. Agent-emitted HTML often includes inline JS — sometimes deliberate (a single-file tool), sometimes incidental (a chart library). Without a Content-Security-Policy default, a careless <script src> can exfiltrate session cookies or local storage from the viewer. Sensible CSP defaults are part of "private by default," not a separate axis.

The X-Robots-Tag corollary

Even with unguessable URLs, leaks happen — a screenshot in a slide deck, a forwarded message, a pasted-into-search bar. X-Robots-Tag: noai, noimageai on every served page tells AI training crawlers (the ones that respect it) to skip the content. It's not a security boundary, but it shrinks the long-tail leak surface considerably.

What this looks like operationally

For a team adopting the new normal:

  1. Pick a host whose default is unguessable URL on the free tier. If "private" is a paid feature, the contract is wrong.
  2. Standardise on per-link gates instead of workspace-wide SSO. SSO scales poorly to "a developer wants to share one report with their PM."
  3. Use email-domain gates for anything containing customer data. They're strong against forwarding.
  4. Use end-to-end encryption only when you can't accept the host as a trust party. For most workloads, the unguessable URL plus an optional password is enough.
  5. Audit your X-Robots-Tag and CSP headers. Both should be opinionated defaults from the host, not something the publisher has to remember.
FAQ

Frequent questions

Why has the default flipped to private? +
Because the volume of HTML produced by AI agents — and the data embedded in it — has grown faster than the social conventions for storing it. Public-by-default was a safe baseline when humans hand-authored each page; it stops being safe when an agent emits a hundred pages a week with API responses inlined.
Isn't an unguessable URL the same as a public URL? +
For attackers brute-forcing URLs, no — sufficient entropy makes guessing impossible. For attackers who get the URL by other means (email forward, screenshot, shoulder-surf), yes — which is why "unguessable" should be the floor, with optional password or email-domain gates layered on top.
What about indexing? +
Unguessable URLs aren't crawlable in the first place. Belt-and-braces, set X-Robots-Tag: noai, noimageai and a restrictive robots.txt; AI training crawlers respect both.
Does end-to-end encryption matter? +
For HTML embedding sensitive data, yes. AES-GCM in the browser with the key in the URL fragment means the host stores ciphertext only — anyone with the URL can decrypt; nobody without it can. For most workloads this is overkill, but it eliminates the host as a trust party for the cases where it isn't.
Keep reading

Related guides

References

Sources and further reading

Adopt the new default.

Stacktree treats every link as private by default. Free tier, no card.

Sign up free →