Problem
A lab (RFC 0035) holds a team's architecture in the console: RFCs, studies and diagrams, reviewed and decided. Teams want to show it to people outside the console: the rest of the company, a customer's security reviewers, an auditor, candidates, or the public. The large ones want it on their own domain, in their own colours, and readable only by the people they name, through their own identity provider.
Each of those is a way to get hurt. A site on a customer's domain is a hostname we answer for: if a customer deletes the site and leaves the DNS record, someone else could claim the name and serve their own content on it with a valid certificate, the takeover Microsoft describes for dangling records (Microsoft). Customer-styled pages on our domain can plant cookies on our sign-in, which is why GitHub moved Pages off github.com in 2013 (GitHub). And an architecture document is exactly what an attacker reads first, so "private" has to mean it, everywhere a copy could leak.
Proposal
A site per lab, private until a person says otherwise
A lab gains a site: a published snapshot of the documents and diagrams its people choose, rendered with the same renderer and the same redaction check as the console. Publishing is a person's action in the console, never a key's, and makes a new immutable version of the site; a bad publish is undone by republishing the previous version.
Every site has an audience, and the default is the team itself:
| Audience | Who reads | How they prove it |
|---|---|---|
| Team (default) | the lab's account members | the platform's sign-in |
| Organisation | everyone the team's identity provider signs in | the team's own OpenID Connect or SAML connection (RFC 0027) |
| Named | listed people, groups from SCIM, e-mail domains | the platform's sign-in or the team's identity provider |
| Link | anyone with a link that expires and can be revoked | a signed, single-purpose link |
| Public | anyone | nothing; still noindex until the team opts in to indexing |
On top of any audience: an IP allowlist, a maximum session length, and per-document overrides (a site can be public with two documents restricted to named people). Moving to Public needs the redaction check to pass on every published document, a second person's confirmation on a team that requires it, and shows exactly what becomes public.
On a domain the team has proved
A site has a default address on a domain of ours that is separate from the platform's (its own registrable domain, on the Public Suffix List), so nothing a site serves can touch a platform cookie. A paid team can add its own hostname.
Everything about DNS lives in one place, the account's Domains settings, not in the Lab: a domain's own page there shows its proof, every hostname under it that something on the platform serves, the record each needs, what DNS currently answers, and the certificate's state. The Lab's Site page only picks a hostname from the account's verified domains and links to that page. The steps:
- The domain is verified once, by the TXT record RFC 0030 already defines and the console
already walks a person through; the hostname must be inside it
(
AccountsService/CoveredBy). - The team adds one CNAME from the hostname to a target made for that site alone,
random and never reused:
<random>.sites.<our separate domain>. A shared target is what lets a stranger claim a name someone forgot; a per-site target that is never reused cannot be claimed by anyone else. - An apex domain (
acme.comitself) cannot hold a CNAME; it needs the DNS provider's ALIAS, ANAME or CNAME flattening to the same target. We do not hand out IP addresses for apex records: a fixed address outlives the site it pointed at. - Wildcards are refused. A wildcard CNAME defeats the per-host proof (GitHub's warning).
The site is served only while all of these hold, checked when the hostname is added and again every day: the domain is verified (RFC 0030's daily recheck), the TXT record is still there, the CNAME points at this site's target, the team's plan includes custom domains, and the site is published. When one stops holding, the hostname answers a neutral page after a grace period and the team is told why. A hostname a team removes stays reserved to that team for 30 days, and its target is retired forever.
Before the first certificate the console reads the domain's CAA records and says exactly which certificate authority to allow if they would block issuance (RFC 8659).
A diagram is drawn here in the RFCs product; this page does not show diagrams yet.
Certificates and the edge
Two ways, decided by measurement before the first customer hostname, both reading the same hostname table:
- for SaaS custom hostnames. issues and renews the certificate, absorbs attacks and hides where the platform runs; 100 hostnames are included, then $0.10 each (). then sees the published content, so it becomes a processor: it goes into the vendor register with its data processing terms before the first customer site.
- Our own edge with on-demand certificates. obtains a certificate on the first connection, and only after asking our hostname table whether the name is a live site; without that check, anyone could point names at us and exhaust our certificate limits (). Let's Encrypt's limits that matter here: 300 new orders per account per 3 hours, 50 certificates per registered domain per 7 days, 5 failed validations per name per hour (rate limits). Certificates are getting shorter (64 days from 2027-02-10, 45 from 2028-02-16), so renewal is watched like any other alert (Let's Encrypt).
Proposed: for SaaS first, for the protection it gives a platform that runs on ; our own edge kept working as the exit, tested against the same table.
Signing in on the customer's domain
The platform's sign-in cookie never reaches a customer's domain. A visitor without a
session on docs.acme.com is sent through the platform's sign-in (or the team's identity
provider), and comes back to docs.acme.com with a code that works once, within 60
seconds, for that host only. The site exchanges it for its own cookie: host-only,
__Host- prefixed, Secure, signed by the platform, with the audience's session length.
The edge checks that cookie on every request, so the edge stays the only authenticator,
as everywhere else on the platform. Signing out of the platform ends every site session
at its next check.
A diagram is drawn here in the RFCs product; this page does not show diagrams yet.
Designed by the team, without their code
A site's look is the team's: colours, light and dark, fonts they upload (served by us, never from a third party), logo, favicon, header and footer links, a landing page written in the same Markdown, a choice of layouts (a documentation layout with a sidebar, a single column, a decision log), and the order and grouping of documents. Teams on the largest plan can add CSS from a checked subset. No customer JavaScript runs on a site: the pages carry a strict content security policy, and diagrams render as sanitised SVG. Every change is previewed on a private address before it is published.
What an enterprise asks for
- Who read what: every view is an audit line (site, document, who or which link, the outcome), never the content; the team reads and exports it, kept a year.
- Indexing off by default with
X-Robots-Tag: noindex, on only by a person's choice and only for public documents (Google). - Export of the site as static files, and of its audit log.
- Limits per site on requests and bandwidth, and a takedown path for abuse.
- Not yet: data residency (the platform runs in one place today), a contractual SLA, and legal hold. Each is named here so no page claims it.
Admin-only first
Like the rest of the Lab, all of this is built and run for admins only, and every check
in this document is an end-to-end test (auth:e2e:lab) before a customer sees it.
Alternatives considered
Sites under our own domain only, no custom domains. The safest, and not what the teams who asked need: the site must look like theirs and live on their name.
A shared CNAME target for every customer (sites.ourdomain), as several products
do. Simpler DNS instructions, and the reason dangling records can be claimed by the next
customer. A per-site target costs one generated name.
Handing out IP addresses for apex records. Works on every DNS provider, and leaves
addresses in customers' zones that outlive their sites. ALIAS or flattening, or a www
host with a redirect, instead.
Letting teams run their own JavaScript, as some documentation products allow. It turns every site into a place to run code on a reader's browser under the customer's name. Tokens, layouts and a checked CSS subset give the look without it.
Password-protected sites as the only privacy. One shared secret, no idea who read what, nothing to revoke per person. Kept only as an expiring, revocable link.
Decision
Open. Proposed: a site per lab, private to the team by default, with audiences up to
public; custom hostnames inside a domain proved by RFC 0030, a per-site CNAME target never
reused, no wildcards, no apex IPs, rechecked daily; for SaaS for certificates
and protection with our own edge as the exit; host-only site sessions issued after the
platform's or the team's sign-in and checked at the edge; tokens and layouts for design, no
customer JavaScript; a view log, noindex by default and export.
Decided by the owner (2026-10-03): custom domains are for the Team plan and above.
The separate domain is inorbit.page, bought 2026-10-03: browsers require HTTPS on
every .page name, and nothing else of ours lives under it.
Not decided: whether the checked CSS subset ships at all.
Publication
The console's lab gains Site (audience, documents, design, the hostname chosen from the account's verified domains, preview, publish, views). Settings → Domains gains, on each domain's page, its hostnames with the CNAME each needs, what DNS answers now and the certificate's state: the one place for DNS on the platform. The developer docs gain the DNS steps for each common provider, the audiences, and the security model. The vendor register gains as a processor before the first customer hostname.
Status log
- 2026-10-03: opened, after a survey of how documentation and hosting products verify customer domains, issue certificates and restrict readers.
- 2026-10-03: DNS stays in one place. A site's hostname, its CNAME and its certificate are shown and managed on the domain's page under Settings → Domains, account infrastructure shared by every product; the Lab's Site page only chooses a hostname from the verified domains. Lab ships admin-only first, like every new console product.
- 2026-10-03: custom domains are a Team plan feature and above (the owner's call).
- 2026-10-03: the separate domain for sites is
inorbit.page. - 2026-10-07: Checked: decisions only (#173, #179, #198); no site is served. Open.