Docs · Mail
A mailbox at a name you own.
Ordinary internet email, at an address built from your Handshake name, in whatever mail client you already use. It speaks JMAP and IMAP. It is not end-to-end encrypted, and this page says exactly what that means before it says anything else.
This is standard internet email. It is protected in transit by TLS, and it is not end-to-end encrypted: our mail servers process the content of your messages, and the storage on disk is not encrypted. We can read your mail. So can our transport provider on the hop through them.
OpenPGP is available on top, opt-in, and it is real — we never hold a private key and there is no endpoint that could accept one. But it encrypts message bodies between correspondents who both use it. It does not hide who you write to, when, or how much, and it does not cover attachments.
If something must not be readable by us, do not send it through here.
Your address
The local part is your name; the domain is hns.one.
| What you hold | Your address |
|---|---|
A Handshake TLD, w3 |
w3@hns.one |
A label matt under w3 |
matt.w3@hns.one |
The dot is inside the local part, which is legal and works. The domain
is our ICANN domain rather than a Handshake one for one unavoidable
reason: MX records have to be resolvable by every mail
server on the internet, and a Handshake name is not.
One mailbox can carry several addresses — your names become aliases of
one inbox rather than several inboxes to check. Some local parts are held
back because the mail service itself needs them: postmaster,
abuse, admin, security and the
rest of the role and service list. Your name is unaffected; only the
address is reserved.
Connecting a client
| Protocol | Setting |
|---|---|
| JMAP | Session URL https://mail.hns.one/.well-known/jmap
(it redirects to /jmap/session) |
| IMAP | mail.hns.one port 993, SSL/TLS |
| Submission | mail.hns.one port 465, SSL/TLS |
| Webmail | mail.hns.one/webmail/ |
Username is your full address. Ports 143 and 587 are closed — both open ports require TLS, so a client configured for STARTTLS on the plaintext ports simply will not connect.
# check the ports are what this page says
openssl s_client -connect mail.hns.one:993 -quiet </dev/null
curl -sI https://mail.hns.one/.well-known/jmap
Mailbox passwords
Your mail client authenticates with a mailbox password that is separate from any account login. It is 23 characters from an unambiguous alphabet, shown exactly once, and never stored in plaintext anywhere on our side.
Where it comes from depends on how your name is held:
- A name bound to a control keyThe operator mints the
password on the mail host, encrypts it to your control key, and
deposits only the ciphertext. Your client fetches it from
GET /api/identity/mail/credentialand decrypts it locally. The public plane never sees the plaintext, and could not — it holds no mail-host credentials by design. - An account-held nameMinted from the operator panel. The
public panel at
app.hns.onecannot mint one and answers with a plain refusal rather than a mysterious error.
Despite the term "app password", there is exactly one credential per mailbox. Minting a new one replaces the old one — every client you have configured stops working until you update it. There is no per-device list and no revoke button.
The only stronger action is sealing the mailbox, which strips every credential so nobody can authenticate at all. That is the mechanism available in the mail server we run; it has no per-account disable flag.
How mail actually flows
Both directions go through a commercial mail provider, and the honest consequence is that they see plaintext too.
Inbound: the provider's MX receives the message, posts the raw MIME to a webhook on our mail host over HTTPS with an HMAC signature, we spool it to disk and deliver it over LMTP to the mailbox. There is no port 25 listener anywhere in this system. A message for an address that does not exist or has been sealed is rejected permanently at the webhook rather than accepted and bounced, so we never emit backscatter.
Outbound: your client submits on 465, and the mail server relays through the same provider as a smart host.
SPF, DKIM and DMARC
These are published once, at the apex of hns.one, and you
inherit them. There is nothing for you to configure and nothing you
could configure — the sending domain is ours. A recipient sees SPF pass
and DKIM pass, both aligned to hns.one.
Because every mailbox sends as hns.one, reputation is
shared. One abusive sender affects everyone's delivery, which is part
of why signup is gated.
Our DMARC policy is p=none and the aggregate-report
address has no mailbox behind it, so those reports currently go
nowhere. Harmless at p=none; still a gap.
Publishing an encryption key
You generate the keypair on your own machine and give us only the public half. A key we generated would have existed on our server, and then "we cannot read your encrypted mail" would be a promise instead of a fact.
gpg --quick-generate-key 'matt.w3@hns.one' default default never
gpg --armor --export --export-options export-minimal matt.w3@hns.one > matt.w3.asc
# keep your own backup — nobody can recover this for you
gpg --export-secret-keys --armor matt.w3@hns.one > secret.asc
Paste the .asc at https://app.hns.one/mail/,
or post it to /api/mail/key (panel token) or
/api/identity/mail/key (control key). A private key is
refused twice over, by two independent checks, on the way in.
Where the key goes
Publishing puts your key in Web Key Directory — the place GnuPG and Thunderbird actually look, with no keyserver involved:
https://hns.one/.well-known/openpgpkey/hu/<hash>?l=matt.w3
https://openpgpkey.hns.one/.well-known/openpgpkey/hns.one/hu/<hash>?l=matt.w3
There is a second, stronger anchor: an OPENPGPKEY record
published in your name's DNSSEC-signed zone, so the key is proved by the
same chain that proves the name. That is an operator-run step — it
is not something the account panel can do today, because the
public plane must never write zone records. Publishing a key gets you
Web Key Directory; the chain anchor is added separately, by us, and the
panel shows which anchor your key currently carries rather than claiming
the stronger one.
You can look up the coordinates for any address at
GET /api/mail/key/lookup?address=. It tells you where to
look and proves nothing on its own — validate the record yourself.
Withdrawing removes the key from the places we publish it. Anyone who already cached it can keep using it until their cache expires, so treat a compromised key as compromised regardless and publish a revocation certificate from your own client.
Reading encrypted mail needs a client holding your private key. Thunderbird over IMAP does it, and Wildroot's own Mail page does it. The webmail deliberately does not — a web page's crypto is only as trustworthy as the last page load.
Limits and honest status
| Limit | Value |
|---|---|
| Mailbox quota | 1 GB |
| Message size through the web tier | 25 MB |
| Send rate limiting of our own | none |
| Backups | nightly, encrypted, restore tested |
No uptime promise, and no guarantee we will not lose mail. Keep a second address for anything that matters.
Mailboxes are created by a queue drained from the operator's machine, not by the public plane. A brand-new mailbox is rejected — not silently queued — until that provisioning lands, which is a few minutes.
Transfer detection is not built. Sealing a mailbox when its name changes hands is implemented and works, but nothing yet triggers it automatically. If you sell a name, tell us.
The mail host's own administration pages are reachable on the public internet. We would rather name that than have you find it.