# Private-by-default HTML hosting is the new normal · Stacktree

Source: https://stacktr.ee/blog/private-by-default-html-hosting

[Skip to content](#main) [Stacktree](/)[Developers](/developers)[Agents](/agents)[Docs](/docs)[Use cases](/use-cases)[Pricing](/pricing)[Blog](/blog)[Dashboard](https://app.stacktr.ee)[Sign in →](https://app.stacktr.ee)      By [ Steve Smith ](/about) · Founder, Stacktree  ·  Last updated May 14, 2026          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 ](https://app.stacktr.ee/?join=1&from=seo_blog_private_by_default_html_hosting)   install npx stacktree-install
Copy
     No card · 3 pages free · about a minute

##  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.

## On this page

  -   01  [ The trigger: HTML-volume from agents ](#trigger-html-volume)
-   02  [ Why the old defaults don't work ](#why-old-defaults-fail)
-   03  [ What "private-by-default" actually requires ](#what-it-requires)
-   04  [ The CSP corollary ](#csp-corollary)
-   05  [ The X-Robots-Tag corollary ](#x-robots-corollary)
-   06  [ What this looks like operationally ](#operationally)

## 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:

  - 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).
 - Per-link password. A second factor for cases where the URL might be forwarded.
 - 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.
 - 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.

 One more default sits at the publish boundary itself: a pre-flight scan that checks the file for API keys, JWTs, and card numbers before it goes live, and blocks by default when the publisher is an agent. Why that belongs in the same posture is its own post: [do AI agents leak secrets?](/blog/do-ai-agents-leak-secrets)

## 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:

  - Pick a host whose default is unguessable URL on the free tier. If "private" is a paid feature, the contract is wrong.
 - Standardise on per-link gates instead of workspace-wide SSO. SSO scales poorly to "a developer wants to share one report with their PM."
 - Use email-domain gates for anything containing customer data. They're strong against forwarding.
 - 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.
 - Audit your X-Robots-Tag and CSP headers. Both should be opinionated defaults from the host, not something the publisher has to remember.
      Fix it now

You've read why the public link is a problem. Paste the artifact here and get a
        private one, no account, and a passcode if you want it.

Paste HTMLDrop a fileno account · 24 h linkHTML to publishAdd a passwordPublish private link
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

   -  [ Private HTML hosting in 2026 The category page this post abstracts. ](/private-html-hosting)
-  [ Why agents need a publish primitive The volume side of the same argument. ](/blog/why-agents-need-a-publish-primitive)
-  [ MCP servers explained How the agent reaches the host. ](/blog/mcp-servers-explained-for-developers)
-  [ Agent-loop hosting The replace-in-place corollary. ](/agent-loop-hosting)

References

## Sources and further reading

   -  [ OWASP — Content Security Policy ↗ The CSP baseline the post references. ](https://owasp.org/www-community/controls/Content_Security_Policy)
-  [ X-Robots-Tag (Google Search Central) ↗ How AI training crawlers honour the noai/noimageai directives. ](https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag)
-  [ AES-GCM (NIST SP 800-38D) ↗ The cipher used for end-to-end encryption. ](https://csrc.nist.gov/publications/detail/sp/800-38d/final)
-  [ IETF — magic link auth (RFC 6238 family) ↗ Magic-link verification descends from this lineage. ](https://datatracker.ietf.org/doc/html/rfc6238)

##  Adopt the new default.

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

 [ Sign up free → ](https://app.stacktr.ee/?join=1&from=cta_blog_private_by_default_html_hosting)   install npx stacktree-install
Copy
       Private hosting for the HTML your agents make.

[](https://betalist.com/startups/stacktree?utm_campaign=badge-stacktree&utm_medium=badge&utm_source=badge-featured)[Featured on](https://devhunt.org/tool/stacktree)[](https://buildlist.io)[Get started free](https://app.stacktr.ee/?join=1)

## Product

- [Page video](/page-video)
- [Ask this page](/ask-this-page)
- [Client spaces](/client-spaces)
- [Templates](/templates)
- [Example deliverables](/examples)
- [Custom domains](/custom-domains)
- [Client feedback](/client-feedback-loop)
- [One-time links](/one-time-view-links)
- [See how pages get read](/page-engagement)
- [Made with Stacktree](/made-with)
- [Security](/security)
- [Watch the demo](/demo)

## Agents

- [All integrations](/agents)
- [Claude Code](/claude-code)
- [OpenAI Codex](/codex)
- [Cursor](/cursor)
- [Claude.ai connector](/claude-ai-connector)
- [Claude Cowork](/what-is-claude-cowork)
- [Meta Muse](/muse)
- [MCP server](/mcp-publish-html)
- [Deploy from Claude Code](/deploy-html-from-claude-code)
- [Skills](/skills)
- [Slack app](/slack)
- [n8n node](/n8n)
- [Agent payments (x402)](/x402)

## Alternatives

- [All comparisons](/alternatives)
- [Head-to-head comparisons](/compare)
- [Tiiny Host](/tiiny-host-alternative)
- [GitHub Pages (private)](/github-pages-private-alternative)
- [Vercel](/vercel-alternative-for-agents)
- [ngrok](/ngrok-alternative-for-html)
- [Display.dev](/display-dev-alternative)
- [Static.app](/static-app-alternative)
- [OpenAI Codex Sites](/openai-codex-sites-alternative)
- [here.now](/here-now-alternative)
- [Shippage](/shippage-ai-alternative)
- [Best private hosting](/best-private-html-hosting)

## Use cases

- [All use cases](/use-cases)
- [Share with clients](/share-with-clients)
- [Send a file to a client](/share-html-file-with-client)
- [Share Claude artifacts](/share-claude-artifacts)
- [Share Jupyter notebooks](/share-jupyter-notebook-html)
- [Host Storybook privately](/host-storybook-privately)
- [Architecture diagrams](/share-architecture-diagrams)
- [AI-generated reports](/host-ai-reports)
- [Internal HTML tools](/internal-tool-hosting)
- [Private HTML hosting](/private-html-hosting)
- [Vibe-coded page hosting](/vibe-coding-hosting)
- [Leave a website builder](/website-builder-migration)

## Learn

- [Blog](/blog)
- [Glossary](/glossary)
- [FAQ](/faq)
- [Where AI output should live](/where-ai-output-lives)
- [Agent-loop hosting](/agent-loop-hosting)
- [Why agents need a publish primitive](/blog/why-agents-need-a-publish-primitive)
- [MCP servers explained](/blog/mcp-servers-explained-for-developers)
- [What changed in the 2026-07 MCP spec](/blog/mcp-2026-spec-changes)
- [Sites in Codex explained](/blog/sites-in-codex-explained)
- [Private-by-default hosting](/blog/private-by-default-html-hosting)
- [An agent paid us $1 (x402)](/blog/agent-paid-to-provision-itself)
- [When a loop hits a paywall](/blog/loop-engineering-paywall)
- [Pricing](/pricing)
- [Self-host (new)](/self-host)
- [Changelog](/changelog)
- [Docs](https://stacktr.ee/docs)
- [About](/about)
© 2026 Stacktree · stacktr.ee

[Privacy](/privacy)[Terms](/terms)[Security](/security)[Dashboard](https://app.stacktr.ee)[npm](https://www.npmjs.com/package/stacktree-mcp)[Sitemap](/sitemap.xml)[llms.txt](/llms.txt)[API spec](/openapi.json)

---
Full markdown summary of the Stacktree marketing surface: https://stacktr.ee/llms-full.txt
