Privacy Policy
HAMANI PTY LTD · ACN 696 864 981 · ABN 48 696 864 981 · Sydney, New South Wales, Australia. Effective 1 August 2026 · Version 1.0.
Every factual statement below about what the software does was checked against the source code; if the code changes, this policy changes with it. It describes what we do, and it is not a compliance certification.
In one paragraph
HAMANI MAIL hosts business email on your own domain. To do that we receive, store and serve your mail. Your mail is yours. We store it in Sydney, Australia. We do not read it, sell it, mine it, or use it to train anything. We do not hold you hostage: there is no lock-in, and you are never locked out of your own mailbox — not for a late invoice, not ever.
1. Who this covers
This policy covers the HAMANI MAIL hosting service: mailboxes on your domain that send and receive mail, and the webmail you read them in.
Two different sets of people appear in the data:
- You and your staff — the people who own and use the mailboxes.
- Everyone who writes to you — third parties whose messages arrive in your mailbox. We hold their information because you received their mail. We handle it as we handle yours.
Sending mail through the HAMANI Email API (bulk, transactional and marketing sends) is governed by the same principles; the specific Australian Spam Act obligations that attach to *sending* are set out in docs/AU-LEGAL.md.
2. What we store, exactly
Nothing in this list is aspirational — each item is a thing the software actually writes.
Your mail
| What | Where | Notes |
|---|---|---|
| Raw message (MIME) of every email received | Amazon S3, Sydney (hamani-email-mailboxes-730558614323, prefix inbound/) | Written directly by Amazon SES when the mail arrives. This is the complete original message, headers and all. |
| Message bodies (plain text and/or HTML) | Amazon S3, Sydney | Extracted from the raw message when we parse it, so webmail can show it to you. |
| Attachments | Amazon S3, Sydney | Stored as separate objects; filenames are sanitised. |
| Message index — mailbox address, message id, conversation (thread) id, folder, read/unread, sender address and display name, recipient addresses, subject line, a 200-character preview of the body, the time received, the spam score and Amazon SES's spam/virus/SPF/DKIM/DMARC verdicts, the storage keys for the bodies, and attachment names/types/sizes | Amazon DynamoDB, Sydney (hamani-email-engine) | This is what makes the message list load fast. Note that the subject and the preview are content, and we say so rather than calling this "metadata only". |
| Copies of mail you send from webmail | S3 (body) + DynamoDB (index), Sydney | When you compose or reply in webmail we keep a copy in your Sent folder, exactly as any mail client does. |
Mail you send through the sending API
Mail sent through the API (not from webmail) is not stored. The message body exists only in memory for the moment it takes to hand it to Amazon SES, and is never written to durable storage. What we keep is a log record of the send: message id, event type (accepted, delivered, bounced, complained…), a timestamp, and a short detail string. No body, no subject, no template data.
Everything else
| What | Where | Notes |
|---|---|---|
| Mailbox accounts | DynamoDB, Sydney | The mailbox address, its domain, the account that owns it, a display name, aliases, mailbox status, quota and bytes used, an optional signature, and optional auto-reply settings (subject, message and dates). |
| Mailbox passwords | DynamoDB, Sydney | Stored as a scrypt hash with a random 16-byte salt unique to each mailbox, compared in constant time. scrypt is deliberately memory-hard, so a stolen hash is expensive to attack. We never store, log or return your password itself — the plaintext exists only for the instant it takes to check or set it. If you forget it, we cannot tell you what it was; it is reset. |
| API keys | DynamoDB, Sydney | We store a SHA-256 hash of the key's secret, never the secret itself. The key is shown to you once, at creation. If you lose it, we cannot recover it — you issue a new one. |
| Suppression list (addresses that bounced, complained or unsubscribed) | DynamoDB, Sydney | Stored as a one-way SHA-256 hash of the address plus the reason and the date. We match against the hash; the address itself is not recoverable from it. |
| Usage counters | DynamoDB, Sydney | A per-account, per-calendar-month count of accepted sends. A number — no recipients, no content. |
| Billing link | DynamoDB, Sydney | Your account id and your Stripe customer id. Card details never reach HAMANI — Stripe holds them. We report usage counts to Stripe; we do not see or store a card number. |
| Your domains | DynamoDB, Sydney | Domain name, owner, the DKIM tokens SES issued, verification status, and the result of the last DNS check we ran. |
| Operational logs | Amazon CloudWatch, Sydney | Ids, counters, states and timings only. A recipient address appears only as a truncated one-way SHA-256 tag, never in the clear. No message body, subject or template data is ever written to a log — this is an absolute rule in our codebase (CONSTITUTION.md §3) and it is enforced by tests. |
Sign-in security data (two-factor, recovery, sessions)
These are live: signing in creates a session, and you can enrol two-factor authentication and set a recovery address from your security settings. Here is exactly what each one stores.
| What | Where | Notes |
|---|---|---|
| Two-factor (TOTP) secret | DynamoDB, Sydney | The shared secret your authenticator app holds. It is stored as-is, because verifying a six-digit code requires re-computing it — a one-way hash is mathematically not an option here, and we would rather say that than imply a protection we do not have. It leaves storage exactly once, when you enrol, so you can scan or type it. It is never logged, never returned by a status check, and never included in any other response. |
| Two-factor backup codes | DynamoDB, Sydney | Stored as scrypt hashes, through the identical code path as mailbox passwords. The codes themselves are shown to you once, at activation, and are then unrecoverable by us. Each is single-use. |
| Recovery address | DynamoDB, Sydney | The other mailbox you nominate for account recovery. Stored in full, because we have to be able to send to it. When you read it back we show it masked (h••••@example.com) — enough to recognise which address you chose, never enough to learn one you did not already know. In logs it appears only as a one-way hash tag, never in the clear. |
| Recovery codes | DynamoDB, Sydney | A 256-bit random code, stored as a scrypt hash, single-use, and time-limited. The code itself exists only on its way to your recovery address; it is never logged. |
| Login sessions | DynamoDB, Sydney | A session id, a SHA-256 hash of the session secret (never the secret), the times the session was created and last used, its expiry, and two device fingerprints described below. |
Device fingerprints — what they are and, more importantly, what they are not. When you sign in we want to be able to tell you "this is a device we have not seen on this mailbox before". To do that without keeping the things that identify you:
- No raw IP address is ever stored or logged. Your IP is reduced to a coarse prefix first — the first three parts of an IPv4 address, the first three groups of an IPv6 address — and only then hashed.
- No raw browser user-agent is ever stored or logged. It is hashed too.
- Both hashes are SHA-256 salted with your mailbox address. That salt is not decoration: without it, an IPv4 prefix has few enough possibilities to be brute-forced straight back out of its own hash, and the same device would produce the *same* hash on every mailbox in the system, which would let us correlate one person across mailboxes. Salted per mailbox, it cannot.
- What a person sees in their session list is the first 16 characters of that hash — enough to tell two entries apart, not enough to be useful for anything else.
- This is not geolocation. There is no geographic database in this system and none is consulted. A changed network prefix is not a place: a mobile carrier moves a phone between prefixes while it sits on a desk, and a VPN can hold one prefix in another country for months. So an alert says *"a device or network we have not seen on this mailbox before"* — it will never say a city or a country, because we do not know one.
What we do not collect
We do not run trackers, advertising pixels or analytics on the contents of your mail. We do not build a profile of you. Beyond the mailbox account above — an address, a display name and a password hash — we hold no personal profile of you: no date of birth, no address, no marketing attributes. At the account level we know an opaque owner id and the domains you verified.
3. Where it lives
Everything above is in AWS's Sydney region (ap-southeast-2): the mail storage, the message index, the send queue, the logs, and Amazon SES itself. Australian mail, hosted in Australia.
Two qualifications:
- This is a statement of fact about where servers are, not a certification. There is no Australian law under which "stored in Sydney" is by itself a compliance guarantee, and we do not present it as one.
- Email crosses borders because email crosses borders. When you email someone overseas, or someone overseas emails you, that message travels through mail servers we do not run, in countries we do not choose. No email host can promise otherwise. What we control — where your mail is *stored* — is Australia.
If we ever configure a service outside Australia (for example a second sending region for failover), we will update this policy before doing it.
4. How it is protected
Exactly what is configured today — no more:
- Encrypted at rest. The mail storage bucket uses S3-managed server-side encryption (SSE-S3). The database table uses DynamoDB encryption at rest with an AWS-managed key. The send queue uses SQS-managed server-side encryption.
- Encrypted in transit to us. The mail bucket and our notification topics require TLS — unencrypted requests are refused. The API is HTTPS only.
- Not public. The mail bucket blocks all public access.
- Backed up. Point-in-time recovery is enabled on the database table.
- Not deletable by accident. Both the mail bucket and the database table are set to be retained even if our infrastructure stack is torn down.
- Scanned. Amazon SES scans inbound mail for spam and viruses before it reaches you; a virus or spam failure is routed to a quarantine folder rather than your inbox.
- Least privilege. Each part of the system is granted access only to the specific resources it needs.
- Rate limited before authentication, so credentials cannot be attacked at speed.
Attachment scanning — what it does, and what leaves
The local layer below runs on your inbound mail today, in addition to Amazon SES's own spam and virus scan. The optional third-party engine is a slot that is not configured — see the second bullet.
There are two layers, and they are deliberately told apart:
- Local checks, which never send your file anywhere. These run inside our own system with no network call at all. They refuse the published EICAR anti-malware test file, files whose first bytes are a Windows, Linux or macOS executable, files whose declared type is executable or script content, and filenames with an executable extension — including the disguised
invoice.pdf.exepattern, which is reported as a *type refusal* and never dressed up as a malware detection. - A third-party scanning engine, which we do not have. Our system has a slot for a commercial scanning service. No such service is configured today — there is no default, and we will not invent one. If the Boss ever configures one, then for an attachment the local checks did not already refuse, the entire file is uploaded to that service, together with its filename, its declared content type and its size. That is the whole point of a scanning engine and there is no version of it that sends less. If that ever happens, this policy will be updated to name the provider and the country it operates in before a single attachment is sent to it — and it would be an APP 8 cross-border question if that provider is overseas.
The verdict rule. A result is one of three things: clean, infected, or unscanned. unscanned exists because the failure that actually infects someone is a system reporting "clean" when nothing looked. With no engine configured, an attachment the local checks did not refuse comes back unscanned, never clean — and the same is true if a configured engine is slow, unreachable, or returns something we cannot read, or if the file is over the size ceiling (10 MB by default), in which case it is not sent to the engine at all. Local checks are not antivirus and this document will never call them that.
Automated spam and phishing classification, and the AI tier
The offline classifier below runs on your inbound mail today and sends nothing anywhere. The AI tier is off unless an Anthropic API key is configured — and by default no key is set, so nothing about your mail leaves our systems. This section describes exactly what the AI tier *would* send if it were ever switched on, so the cost is on the record before that decision.
Again two layers:
- The offline classifier, which sends nothing anywhere. No key, no network, no third party. It looks at sender display-name spoofing, a Reply-To that points somewhere other than the sender, link text that lies about where the link goes, punycode and mixed-alphabet lookalike domains, links to bare IP addresses, high-abuse domain suffixes, and urgency / credential-request / advance-fee wording. It is a complete classifier on its own, not a degraded one, and it is what runs when no AI key is set.
- The AI tier, which is off unless a key is configured. With an Anthropic API key set, each inbound message produces one call to the Anthropic Messages API (
api.anthropic.com). With no key set, nothing leaves — not one byte, not one request.
Exactly what is sent to the Anthropic API when that tier is on. This is the complete list; there is nothing else in the payload:
| Field | What it is |
|---|---|
subject | Your message's subject line, verbatim, up to 300 characters. |
from | The sender's display name (to 200 characters) and email address (to 200). |
replyTo | The Reply-To address, if the message had one. |
linkHosts | Hostnames only — up to 25 — from the links in the message. Never full URLs. The path and query of a link are where a per-recipient tracking token lives, and a tracking token identifies the reader, so it never leaves. |
localFindings | Up to 12 of the offline classifier's own findings, in words. These quote evidence from the message — the matched phrase, a link's visible text, the sender's display name — so they are message content too, and we are not going to pretend they are only "rule names". |
bodyExcerpt | A bounded plain-text excerpt of the message body, 2,000 characters by default, with every URL inside it reduced to [link:hostname]. Setting the limit to 0 sends no body at all. |
Say the cost out loud. That excerpt *is* your correspondent's message content, sent to a third party outside Australia. Reducing URLs to hostnames does not change that: whatever else was written in the first 2,000 characters — names, figures, addresses — goes with it. That is why the tier is off unless a key is deliberately set, why the limit is settable to zero, and why a private mailbox (§4A) is never classified at all. If HAMANI ever enables this tier, this policy and docs/AU-LEGAL-HOSTING.md §4 must be updated first, because sending message content to a US-based API is a cross-border disclosure question, not a configuration change.
No message is ever failed by a classifier. If the AI call times out, errors, is refused, is cut off, or returns something that does not match the required shape, the offline verdict is used instead and it says so in its own reasons. The model is also never allowed to invent a suspicious link: only links genuinely present in the message survive into the result.
And what is not true, stated plainly:
- An ordinary mailbox is not end-to-end encrypted. We hold the encryption keys. That means HAMANI is technically capable of reading stored mail — see §6 for the rules we work to. There is now one exception, and exactly one: a mailbox you have deliberately put on the zero-knowledge private tier (§4A), where we hold ciphertext we cannot open. Unless you have done that, for the mailbox you did it to, this bullet stands.
- Mail in transit between mail servers is not guaranteed to be encrypted. SMTP encryption is opportunistic: it happens when the server at the other end supports it. That is true of all email everywhere, and we do not require TLS on inbound mail.
- We hold no security certifications. We are not ISO/IEC 27001 certified, we have no SOC 2 report, no IRAP assessment, and no Essential Eight maturity assessment. If a certification matters to you, we would rather lose the sale than claim one we do not hold.
4A. The zero-knowledge private mailbox — optional, and irreversible
Numbered 4A rather than 5 so that every existing cross-reference in this document and in
docs/TERMS.mdstill points where it did.
A mailbox can be put on a private tier. This is off by default, it is opted into per mailbox, and you must acknowledge the consequences below before it can be turned on — the software refuses the request otherwise.
What it does
- Your browser generates a key pair and a passphrase-derived key on your own device. The passphrase never leaves that device and never reaches our servers.
- We keep your public key in the clear, and your private key only as an opaque blob that your passphrase locks. We never open that blob, and we could not use it if we did.
- When mail arrives for that mailbox, our server encrypts each body and each attachment to your public key and stores only the ciphertext. Nothing readable is written to disk.
- The subject line and the message preview are withheld too — stored empty rather than stored readable. Subject lines are the single most revealing piece of metadata a mail host holds, and keeping them in the clear would quietly undercut the whole thing.
- Drafts and copies of mail you send are encrypted the same way, with their subjects and previews withheld the same way. An earlier version of this software encrypted received mail only, and stored drafts and Sent copies readable in the same mailbox — your own words, in the mailbox whose whole promise is that we cannot read it. That was found by an adversarial review of our own code and fixed; this paragraph exists so the correction is on the record rather than quietly absorbed.
- Attachment filenames and content types are encrypted too, and the storage key is opaque. A filename like
Q3-redundancy-list-FINAL.xlstells you almost everything the file contains, and it was previously readable both on the index and inside the storage key itself. - What is NOT encrypted, and what we can therefore read on a private mailbox: who sent each message, who it was addressed to, when it arrived, how large it is, and Amazon SES's spam and authentication verdicts. We need those to accept, route and list your mail. If a sender puts something revealing in their own Message-ID header, that is theirs and we leave it as they sent it. Everything in this bullet is readable by us; nothing above it is.
- There is deliberately no decryption function anywhere in our server code. This is structural, not a matter of our good behaviour: an operator with complete access to our production systems has nothing to decrypt *with*.
- The cryptography is entirely standard and comes from audited implementations (the browser's own Web Crypto, OpenSSL underneath in our server): RSA-OAEP with SHA-256, AES-256-GCM, and PBKDF2-HMAC-SHA256 at 600,000 iterations to turn your passphrase into a key. We have not invented any cryptography and will never describe this as though we had.
What it costs you — read this before opting in
These are consequences, not caveats. They are the price of the guarantee, and they are shown to you by the software itself before you can turn it on:
- If you lose your passphrase, your mail is permanently unreadable. There is no reset, no recovery, no support ticket, no court order and no backup that helps. We cannot open it because we structurally cannot open it. That is exactly what makes the promise real — a vault we could open for you is a vault we could open for anyone.
- Search does not work on a private mailbox. The server refuses the search outright and tells you why, rather than returning an empty list that looks like "no matches". We cannot search what we cannot read. Searching a private mailbox has to happen in your browser, after you have unlocked it.
- Spam and phishing filtering does not run on a private mailbox — neither the AI tier nor the offline one, because even an offline verdict is a fact about content we said we would not inspect. You will receive spam unfiltered. This is enforced in the code as a required, un-forgettable input, not as a policy someone has to remember.
- Enabling it does not encrypt mail you already received. Anything already in the mailbox stays exactly as it was.
- A vault cannot be replaced. Publishing a second one would orphan every message encrypted to the first, so the software refuses it. A new vault means a new mailbox.
- It does not protect you from your own device. If the computer or browser you unlock the mailbox on is compromised, none of this holds. What it protects you from is us: our operators, our database, our backups, and a subpoena served on us.
The limitation we will not soften
Mail arrives from the internet in plaintext. That is how email works: the sending server hands the message to Amazon SES, SES hands it to our engine, and our engine must hold the message in memory in order to encrypt it. So for the instant between arrival and encryption, your message exists unencrypted on our infrastructure.
What the private tier buys is everything after that instant: nothing readable is written to disk, nothing is searchable, nothing is readable by an operator, a backup, a database breach, or a subpoena served on us. That is a real and large difference from a provider that stores mail it can read. But it is not "your message never touches our servers unencrypted", we will never say that, and any provider that offers zero-knowledge mail over ordinary email has this same property whether or not they mention it.
5. How long we keep it
| Data | Retention |
|---|---|
| Your mail (raw message, bodies, attachments, index) | Kept indefinitely, until deleted. There is no automatic expiry. Your inbox is not a product that silently throws mail away. See the warning below. |
| Suppression list | Kept indefinitely — it is what stops us mailing someone who bounced or unsubscribed. |
| Usage counters | Kept indefinitely as billing history. |
| API keys | Until you revoke them. Keys do not expire on their own. |
| Send idempotency and rate-limit records | 24 hours (DURABLE_RECORD_TTL_SECONDS, default 86,400 seconds). |
| Monthly fair-use counter | 35 days. |
| Failed sends parked in the dead-letter queue | 14 days. |
| Operational logs | No retention limit is configured today, so logs are kept until we set one. They contain metadata only (see §2). |
Read this before you rely on "Trash". Moving a message to Trash moves it, it does not delete it — the message stays in our storage until the mailbox is deleted. Deleting a mailbox (from your admin console) is a real, permanent erasure: it walks every message in that mailbox, deletes its stored bodies and attachments from S3, and then removes the mailbox account — so recreating the same address later starts empty and inherits nothing. That erasure cannot be undone. What is still outstanding is a per-message permanent-delete and an automatic erase-on-account-closure sweep; both are tracked in
docs/AU-LEGAL-HOSTING.md§5. Retaining rather than auto-deleting is the deliberate safe default (an accidental delete must never destroy your correspondence), and deleting the mailbox is the deliberate way to erase.
6. Who can access your mail, and when
- You, through webmail, using your mailbox credentials.
- The HAMANI hub, on your behalf. Webmail lives in the HAMANI hub, and the hub is what talks to the mail service. The mail service only answers requests that are cryptographically signed with a shared secret held by the hub — a signature older than five minutes is rejected — and it checks that the mailbox being read belongs to the account making the request. Without that secret, the mail endpoints are closed entirely.
- HAMANI personnel with production access, technically. We hold the keys, so we are capable of reading stored mail. Our rule is that we do not — mail is accessed only where it is genuinely necessary to operate the service (for example, investigating a fault you have reported), and never for marketing, profiling, model training, or curiosity.
- Nobody else. We do not sell your data. We do not share it with advertisers. We do not give it to other customers.
If we are compelled by a valid Australian legal process to disclose data, we will comply with the law, and we will tell you unless we are legally prohibited from doing so.
On the last two points: the technical guarantee here is that access requires production credentials and a signed request. The rest is a policy commitment by a small Australian business — a promise backed by our word and our contract, not by a control that makes it impossible. Treat it as what it is.
The one place that is different. For a mailbox on the zero-knowledge private tier (§4A), the third bullet above does not apply to the stored contents of that mailbox: we hold ciphertext and no key, so "HAMANI personnel, technically" is not true of it. We can still see that the mailbox exists, who sent to it and when, and how large the messages are — that routing information is what the internet used to deliver the mail and we cannot encrypt it away. If we are compelled to disclose data from a private-tier mailbox, we can hand over what we hold, and what we hold is unreadable to us and to whoever receives it.
7. Your data is yours
- You own your mail and your data. Hosting it does not give us any rights over it.
- You can get it out. If you leave, we will give you your mail. How that works today: there is no self-service export button in the product yet. Export is a request you make to us and we fulfil manually. It is free, and we will not slow-walk it. A self-service export is on the roadmap; when it ships, this section gets updated.
- No lock-in. HAMANI MAIL is pay-as-you-go in Australian dollars, with no fixed monthly fee and no minimum term. You can stop whenever you want. Ending the service does not cost you your mail — see
docs/TERMS.md§5. - Non-payment never locks you out of your mailbox. Sending may pause. Your mail stays yours and stays readable. This is a deliberate product rule, not a courtesy.
8. Access, correction and complaints
- Access. Ask us and we will tell you what personal information we hold about you and give you a copy.
- Correction. If something we hold about you is wrong, tell us and we will correct it. There is no charge for a correction.
- Complaints. Tell us first. Write to [email protected] and we will investigate and respond within 30 days. If you are not satisfied with our response, or we do not respond within 30 days, you may complain to the Office of the Australian Information Commissioner (OAIC) — the OAIC asks that you complain to the organisation first and give it 30 days before bringing the complaint to them. The OAIC's complaint pathway is at <https://www.oaic.gov.au/privacy/privacy-complaints>.
This policy is deliberately written to describe what we do and to offer access, correction and a complaint pathway as commitments, so it holds regardless of how any small-business threshold under the Privacy Act 1988 (Cth) applies to us.
9. Data breaches
If personal information we hold is accessed, disclosed or lost without authorisation, we will assess what happened promptly, contain it, and tell the people affected where the breach is likely to cause them serious harm. Where the Notifiable Data Breaches scheme in Part IIIC of the Privacy Act 1988 (Cth) applies to us, we will also notify the Australian Information Commissioner as that scheme requires.
10. Changes to this policy
We will keep this current. If we change something that materially affects your data — where it is stored, how long we keep it, who can see it — we will tell customers before the change takes effect, not after. If we ever configure an overseas attachment-scanning engine, or switch on the AI classification tier (which would send bounded message content to an API outside Australia), we will update §4 to name it before the first message is sent, because that is a cross-border disclosure decision, not a configuration change.
_HAMANI PTY LTD · ACN 696 864 981 · ABN 48 696 864 981 · Sydney, New South Wales, Australia. © 2026 HAMANI PTY LTD. HAMANI MAIL Privacy Policy, version 1.0, effective 1 August 2026. Privacy contact: [email protected]._
Hamanimail
← Back to site