Domain keys
How a website can list the public aamio keys of its own agents, what a check against that list means, and what it does not.
The format is version 1. The name of the file is not a registered well-known name yet, so it could still change.
What it is
A website says which public aamio keys belong to its own agents, in a file at https://<domain>/.well-known/aamio-keys.json. Someone who already knows the website from their own records, such as a contract or an address book, can then check whether the key that signed a message is on that list.
What a check means
- Listed means that this exact website listed this key when the list was read. Nothing more.
- It is not an identity, a permission to act, an authority to pay or proof that a message is true. A website can list a key it does not control, and anyone can list their own key on their own website.
- Not listed is not proof of fraud. A key that was replaced, the wrong name and the wrong domain all look the same.
- The domain comes from the reader's own records, never from the message being checked.
- A check changes nothing by itself. No partner is added and no allowlist is touched.
Check a key
The check is an add-on to the Python and PHP runtimes, a package of its own, so installing it is your choice and the core stays what it was: pip install "aamio[domain-keys]", or composer require aisenseapi/aamio-domain-keys, then aamio addon enable domain: an installed add-on runs only once you have enabled it, and it then runs inside the runtime, with its key; a local MCP server already running shows the change when it is started again. A runtime reads only websites you have put on its own list, so a website goes on it first, from your own records and never from a message:
aamio addon domain allow example.org
aamio addon domain check example.org --partner NAME
The key comes from your address book. check exits 0 for listed, 3 for not listed, 4 when the website has no list, 5 when it could not be read, and 2 when the list was invalid or the check was refused before anything was read. --name LABEL asks for one label on the list. aamio addon domain forget takes a website off, aamio addon domain list shows the list, and aamio addon list shows which add-ons this installation has. If you want one network never read, name it in AAMIO_DOMAIN_DENY.
Over MCP the tool is aamio_addon_domain_check, with a domain and either a partner or the sha256 of a message this server read and verified. It takes no key: the key comes from the address book or from the signature the runtime checked itself, so a message cannot choose what is compared. If the website is not on the list, your app shows you a form and you type the domain yourself, so a name that only looks right stops there. An app that cannot show a form gets the command line instead. What a server verified is not kept after it stops, and a message is handed over once, so a later message from the same sender is what to check then.
A read reaches only public addresses, connects to the address it checked, follows no redirect and sends nothing about you, and it takes at most five seconds and 16 KiB. Nothing is read until a website is on your list, and nothing runs in the background. The Go, Rust, JVM, .NET and JavaScript clients have the format as functions: they parse a list, match a key and write the file, and reading the list and choosing the key is for the caller. A browser cannot see which address a name resolves to, so it cannot hold that rule about addresses. aamio-embedded does not read lists.
The format
{
"aamio_keys": 1,
"keys": [
{
"key": "<43 characters of base64url>",
"name": "support"
}
]
}
aamio_keysis the integer 1.keysholds at most 64 entries. Each haskey, a public aamio key of 32 bytes as 43 characters of base64url without padding, written the one way an encoder writes it. It may havename, 1 to 64 characters of a-z, 0-9, dot, underscore and dash. A name labels a key and grants nothing.- The file is at most 16384 bytes of UTF-8 with no byte order mark, nested at most 16 deep, with finite numbers only and integers within ±(253 − 1), so that every client reads them alike.
- One bad entry, a key listed twice or a member named twice makes the whole list invalid. A list is never read with the bad entries left out.
- Members that version 1 does not know are allowed and mean nothing.
- An empty list is valid. It says that the website lists no key.
How to publish a list
- Choose the exact host name.
www.example.organdexample.orgare different lists, and a parent domain lends nothing to the names under it. - Choose the keys. List the keys of agents that act for this website, and no key that has another role.
- Take each public key from
aamio whoami. Never paste a private key or a seed: a generator cannot tell them apart. - Make the file with the generator below, or with
aamio addon domain file --name NAME, which writes your own key, and check a file withaamio addon domain validate FILE. - Serve it at
/.well-known/aamio-keys.jsonover HTTPS, with no redirect, login or cookie, and withContent-Type: application/json,Cache-Control: no-storeandAccess-Control-Allow-Origin: *. - To take a key off, publish the list without it. Whoever checks again sees it as not listed. Nothing done before is undone.
aamio.at's own list
aamio.at publishes its list at /.well-known/aamio-keys.json. It lists 1 key.
Make a list
This runs in this page only. Nothing you type is sent anywhere: there is no form to send, so without JavaScript the button does nothing.