This site is being rebuilt and some pages are out of date. For current details, write to reach@inorbit.hr. This notice goes away when the rebuild is done.

No analytics unless you allow it, no tracking. This site keeps in your browser the language you pick, the theme, its colour, which site you chose, the currency on the pricing page and that you closed this notice; signing in adds session cookies. The legal page has the details.

Sign in

← Back to Platform

RFC 0030decided2026-10-03

Domains, proved once and used everywhere

One DNS record proves an account controls a domain, in the console, the API or iohr; the proof gates single sign-on and everything our cloud sends at it.

Problem

Two things the platform is about to do need the same fact: that the person asking controls a domain.

  • Single sign-on for a team (RFC 0027) sends everyone with an address at company.hr to the company's identity provider. Without proof, anyone could claim the domain and capture its people's sign-ins. RFC 0027 decided how to prove it: a DNS TXT record at _inorbit-verify.company.hr, checked by the accounts service, a domain verified for one team at a time.
  • Testing from our cloud (RFC 0031) sends checks and load at an address. Without proof, the platform becomes a tool for hitting someone else's site. The chaos tool we run on our own stack takes any address today, which is acceptable only because it is ours.

The IETF's work on domain control validation describes how this is done well: an underscore name that cannot collide with a real host, a random token per account, an expiry, lookups from more than one place, and removal when no longer needed (draft-ietf-dnsop-domain-verification-techniques-13, 2026-06-22).

Proposal

Domains are a place of their own in the console, under the account (personal or team), and the same objects over the API and in iohr. RFC 0027's Security page links to them rather than holding them.

A wizard, not a form

Adding a domain is a guided path in the console, because for most people it is the first thing they do and a wrong DNS record is the most common reason it fails:

  1. The domain. A person types company.hr. The wizard checks it is a real registered domain and not already verified by this account.
  2. The scope. The whole domain and everything under it, or one subdomain such as staging.company.hr and only what is under that (see Scope below).
  3. The record. The platform makes a token, 160 random bits written in base32 so DNS keeps it intact, bound to this account and this domain, and shows the one record to add: _inorbit-verify.company.hr TXT "inorbit-verify=<token>", with a copy button. It looks up who serves the domain's DNS and shows that provider's own steps (, Route 53, Google Cloud DNS, Azure DNS, the common registrars), or general steps when it does not recognise one.
  4. The check. The wizard checks by itself while the page is open and says what it sees: nothing yet, a record with the wrong value, or the right one. The accounts service asks more than one public resolver, in different networks, and validates DNSSEC where the zone has it; a record seen by only one resolver does not count.
  5. The confirmation. A summary of what was proved (the domain, the scope, how and when) and what it unlocks for this account, which the person confirms. Only then is the domain verified. Unconfirmed tokens expire after seven days.
  6. What next. The last step offers the two things a verified domain is for: setting up single sign-on for a team (RFC 0027) and installing an agent for this domain (RFC 0029), which continues straight into the agent's own wizard with the domain already chosen.

The API and iohr domains follow the same steps without the pages: add, read the record, verify, confirm.

Scope

A verified domain covers itself and every name under it (api.company.hr, staging.company.hr). A company that wants less proves a subdomain instead (staging.company.hr), and only that subtree is covered.

One account at a time, kept true

  • A domain is verified for one account at a time, as RFC 0027 decided for teams. A second account that proves the same domain takes it over, the first is told, and the change is in both audit logs.
  • The record is checked again every day. If it disappears, the domain becomes unverified after three failed days in a row, and everything that depends on it stops: checks and load from our cloud are refused, and single sign-on falls back to the owner's own sign-in.
  • Removing a domain in the console tells the person they may now delete the record.

A diagram is drawn here in the RFCs product; this page does not show diagrams yet.

What depends on it

Feature Needs
Single sign-on and provisioning for a team (RFC 0027) the e-mail domain verified for that team
Checks, load and capacity sweeps run from our cloud (RFC 0031) every target address inside a verified domain
An agent (RFC 0029) acting on a named host the host inside a verified domain the agent is bound to, as well as the agent's local policy
An agent acting on an address with no public name (a bare private address, db.internal) the agent's local policy naming it; no domain can be proved for it
Faults never from our cloud; only through an agent

A diagram is drawn here in the RFCs product; this page does not show diagrams yet.

The same everywhere

  • API: GET/POST /v1/accounts/orgs/{account}/domains, GET/DELETE …/domains/{domain}, POST …/domains/{domain}/check and POST …/domains/{domain}/confirm, under new scopes domains:read and domains:write, deny by default (RFC 0016).
  • iohr: iohr domains add|verify|list|rm, printing the record to add and, with --wait, checking until it is seen.
  • Events: domain.verified, domain.unverified and domain.transferred, carrying ids, never content (RFC 0022), and domain.* entries in the audit log.

Alternatives considered

A file at a well-known URL on the domain. Common, and it proves control of one web server, not the domain; every subdomain would need its own.

A CNAME pointing at us. Lets us renew the proof without the company touching DNS again. Useful later for automated renewal; the TXT record is what every DNS provider and every security team understands today.

Verify per feature. Single sign-on and testing would each ask for their own record. One proof, used by both, is less work for the company and one thing for us to keep true.

Trust the address a person types. What the internal chaos tool does, and the reason it cannot be offered to anyone else as it is.

Decision

Decided 2026-10-07, built and live as proposed: one TXT record per domain per account, as RFC 0027 decided, looked up from several resolvers, covering the domain and its subdomains, re-checked daily, and the one gate for single sign-on and for everything our cloud sends at a customer's systems.

Publication

The console gains Domains. The developer docs gain a page on proving a domain with each common DNS provider and the API reference the domain endpoints and scopes; the command line's reference gains iohr domains.

Status log

  • 2026-10-03: opened, extending RFC 0027's domain record to every account and to testing from our cloud, with RFC 0028, 0029 and 0031.
  • 2026-10-03: adding a domain is a wizard that ends in single sign-on or an agent, and an agent acts on named hosts only inside the verified domains it is bound to (RFC 0029).
  • 2026-10-03: built in the accounts service: the accounts.domains table, lookups through three public resolvers over DNS-over-HTTPS with two that must agree, the daily re-check that unverifies after three failed days, transfer between accounts, the scopes domains:read and domains:write, the events, and the platform's CoveredBy check. The console gains Domains with the six-step wizard, and the developer docs a page per DNS provider. The API's verify step is two calls, check and confirm.
  • 2026-10-07: Decided: built and live. Domains (#137) run in accounts at 932c4445 and the wizard in console-ui at 3a40912a; iohr domains merged in inorbithr/sdk#40. Single sign-on, which will use the same gate, is RFC 0027 and not built.

← Back to Platform