HNS.ONE

Docs · Gateway mirror

An ordinary-browser address for a name ordinary browsers can't open.

A Handshake name resolves in Wildroot and in anything else running a Handshake resolver. In Chrome it does not exist. The mirror gives your name a second address — <name>.hns.one — served under a certificate issued for that exact hostname, so you can send a link to somebody who has never heard of any of this.

What it is, precisely

The mirror is a compatibility shim. It is not a second copy of your site and it is not a proxy to a server of yours.

What it does: takes a request for <name>.hns.one, reads the content pointer in the zone for that name — a TXT record of the form ipfs=<cid> or ar=<txid> — fetches those bytes from IPFS or Arweave, and serves them. Every response carries X-HNS-Gateway: passthrough; content addressed on ipfs/arweave.

Because the pointer names a hash, the bytes we serve are the bytes you published, and anyone can check that independently. That is the part of the mirror that does not require trusting us.

We terminate TLS, so we can see and alter gateway traffic

That is inherent to any gateway: we hold the private key for <name>.hns.one, and a visitor's browser is trusting us not to change what it gets. The content addressing makes tampering detectable by someone who checks — it does not make it impossible, and the browser is not checking it for them.

The native path — opening https://yourname/ in a client that resolves Handshake — is the trustworthy one. Wildroot always prefers it and never routes through the mirror. Treat the mirror as what it is: the address you give to people who are not running that client yet.

The two modes

The distinction that matters is who answers DNS for your name.

  • HNS.ONE-hostedYou delegated the name to ns1.hns.one/ns2.hns.one. We hold the zone, so the content pointer, the gateway address record and the DANE pin are all things you edit in the panel. This is the path everything else on this site assumes. See Delegate.
  • PassthroughYour DNS stays exactly where it is; we touch none of it, and you prove control with a TXT record instead. In return you get the mirror hostname and its certificate.
Read this before choosing passthrough

Passthrough registration issues the DNS record and the exact certificate, and that pipeline works. But the gateway has no code that fetches from an origin server of yours. It serves content-addressed bytes named by a pointer record in a zone we hold, and nothing else — so a name whose DNS we do not serve currently resolves to a mirror host that answers 404 Not hosted here.

In other words: today the mirror can give you the hostname and the certificate, but it cannot serve your existing self-hosted site through them. If that is what you need, say so — it is a known gap with no code behind it yet, not a configuration you are missing.

Why the certificate has to be exact

A TLS wildcard matches exactly one label. *.hns.one covers yourname.hns.one but cannot cover blog.yourname.hns.one — so multi-label mirrors are impossible without a certificate per hostname.

The second reason is blast radius: a gateway holding a broad wildcard can impersonate every name beneath it. One certificate, one hostname, one -d flag, issued over HTTP-01 against the exact host we are about to serve.

# check what your mirror is actually presenting
openssl s_client -connect hns.one:443 -servername blog.10103.hns.one </dev/null \
  | openssl x509 -noout -subject -ext subjectAltName

On a correctly issued mirror that prints one subject and one SAN, both your hostname.

A wildcard certificate is still live beside the exact ones

The edge's default server block still serves a multi-SAN *.hns.one certificate for hosts that have no per-name block. Retiring it is the last step of the migration and is deliberately last, because removing it first would take working names offline. So "HNS.ONE holds no wildcard for your name" is not something we can honestly say today.

Getting one

Start the claim

At https://app.hns.one/names/verify/. You get a token, good for 24 hours.

Publish the proof

A TXT record at _hnsone.<name> with the value verification=<token>. For a TLD you own, delegating to our nameservers is accepted instead — only the holder can set NS on-chain, so it proves the same thing.

We verify and provision

Within about five minutes: the exact A record, a wait for it to propagate, then certificate issuance, then the route. In that order, always — the certificate is never requested for a name that has not just been proved.

A label under a TLD we already operate takes a different route: the database row is the record, there is no second registry to check against, and it inherits its parent zone's wiring rather than getting a certificate of its own.

# the record you publish
_hnsone.yourname.  TXT  "verification=<token from the panel>"

# check it the way we will
dig +short TXT _hnsone.yourname @ns1.hns.one

Ownership monitoring and suspension

Proving control once is not enough — names change hands. Once a day we re-check the proof for names verified by TXT: not merely that a record exists, but that it still carries the exact token that was consumed for that claim, compared in constant time.

If the proof is gone, the route is suspended: the per-name server block is removed and the mirror stops being served. DNS and the certificate are deliberately left in place, so re-enabling costs no new issuance.

If the check cannot get an answer at all — a resolver blip — nothing is suspended. Unknown is not the same as absent, and a DNS hiccup must not take a working site down.

What this monitoring does not cover

Labels issued under a TLD we operate are exempt by design — our database is the record, so there is nothing external to re-check.

Suspension removes the per-name route. Where a zone also has per-zone wildcard wiring, another server block may still match the hostname, so a suspended mirror is not guaranteed to be fully dark. We have not tested that case end to end.

And the honest scope: the one mirror live today is a label under one of our own TLDs, which is out of scope for the daily re-check. The monitoring code and its schedule are real and running; it has not yet had a third-party name to act on.

Limits

LimitValueWhy
Object size served25 MB Hard cap in the gateway; larger objects return 502
Content cache300 s In-process, plus Cache-Control: public, max-age=300 on responses
Certificates per week50 Let's Encrypt per registered domain — the ceiling on new mirrors per week, unless names are batched into shared certificates
Identical name set5 per week Let's Encrypt duplicate-certificate limit, no override
Provisioning queueevery 5 min, 20 per run The worker runs on the operator machine, not the edge
Request rate limitingnone Specified, not deployed. Do not assume the gateway throttles anything

Provisioning runs from the operator's machine because creating the public DNS record needs registrar credentials, which are deliberately not on the public edge. The tenant plane records the intent; home reaches out. Nothing reaches in.

Unregistered names

A hostname under hns.one that we do not serve returns HTTP 404, "Not hosted here". It never falls back to some other name's content, and a name whose owner has opted out of the gateway stops resolving in the gateway form entirely rather than returning a page that would confirm the name exists.

It is a 404, not NXDOMAIN — for now

Our design notes say unregistered gateway names should return NXDOMAIN, and per-name records are created with no wildcard precisely so that becomes possible. But a *.hns.one wildcard A record is still published today, and a DNS wildcard answers at any depth beneath it. So anything.hns.one currently resolves to our edge and gets a 404 from the gateway.

Retiring that wildcard is the same migration step as retiring the wildcard certificate, and it has not happened.