The address as a universal anchor
One /128 you already hold exclusively can anchor every key, wallet, endpoint, and claim an agent has - checkable by a stranger with dig and zero accounts, forever.
Every team building agents eventually reinvents the same bad wheel:
- "How does someone verify this agent's payout wallet is really its wallet?" - gets a Discord pin.
- "How does someone verify this is really the agent's SSH host key?" - gets a Slack message and a screenshot.
- "How does someone verify this output came from the agent and wasn't edited after?" - gets nothing; you just trust the log you were handed.
Each is the same problem - bind a piece of data to an identity so a third party can check it without asking you - solved a different, worse way every time: a verified badge that only means something inside one platform, a tweet that disappears, a support ticket that says "yes, that's really us." None of it survives the platform going away, and none of it is checkable by a machine.
DNS already solved this, generically, decades ago: publish a record at a name, sign the zone, let anyone with a resolver check it. Whisper's contribution isn't a new primitive - it's giving every agent a name it can publish records at, for free, the moment it exists. This page is the generalized pattern behind DANE, did:web, and RDAP individually - read together, they stop looking like three unrelated specs and start looking like one anchor with three doors.
The pattern, stated once
Three ingredients, always the same shape, no matter what you're pinning:
- A name that's provably yours. Whisper derives it mechanically from the address - see Identity for the five-step transform - so the name isn't a label in someone's database, it's a pure function of a
/128you hold exclusively out of2a04:2a01::/32(AS219419). - A record - or a signed document - published under that name.
TLSAfor a TLS key,SSHFPfor an SSH key,OPENPGPKEYfor a PGP key,SRV/URIfor an endpoint; or, for a richer claim (a wallet, a capability), a signed JSON document served over HTTPS at adid:webwell-known path - still at your name, still anchored by the same DNSSEC chain and DANE-pinned TLS key. The container is just a container - the property that matters is that it lives at your name. - DNSSEC signs the whole thing to the root. One chain of trust, RFC 4033–4035, the same chain that already proves the address is yours now proves the record is too - no separate PKI, no separate account, no separate "verified" badge to maintain.
Anyone who wants to check the pin does the same three-step read in reverse: resolve the name, validate the RRSIG to the IANA root, compare the payload. No API call to Whisper is required at any point - that's the keyless half of the two-tier design every Whisper surface follows (see Verify an agent).
Why this generalizes. A TLSA record is a key pin. A TXT record with a wallet address is an asset pin. A TXT record with a content hash is a provenance pin. They're all "a signed pointer at a name you own" - once you see the shared shape, you stop asking "does Whisper support pinning wallets?" and start asking "what haven't I pinned yet?"
Applying it: three concrete pins
1. A TLS key - the pin you already have
Every Whisper agent gets this one automatically. A TLSA record at _443._tcp.<name> pins the exact SPKI hash a client must see in the TLS handshake - no CA, no trust store, per RFC 6698. Full mechanism in DANE & TLSA; the short version:
# With stock tools
dig +short TLSA _443._tcp.acef2002a323d40d4.t7af9242c44554e0f8e183ac8e6fbf645.agents.whisper.online
# 3 1 1 b653a4ef...fcb82d1d
# With Whisper
whisper verify --trustless acef2002a323d40d4.t7af9242c44554e0f8e183ac8e6fbf645.agents.whisper.online
# dane pass DNSSEC-root served leaf SPKI-SHA256 == TLSA pin
2. A payout wallet - the pin nobody's automating yet
An agent that gets paid needs a wallet address bound to its identity strongly enough that a counterparty doesn't have to trust a chat message. Publish it as a Verifiable Credential - a compact ES256 JWS whose issuer and subject are the agent's own did:web, signed with the assertionMethod key its DID document already publishes (the same key DANE pins under _443._tcp.<name>, not a new one you generate) - served as a static file next to the agent's did.json:
https://acef2002a323d40d4.t7af9242c44554e0f8e183ac8e6fbf645.agents.whisper.online/.well-known/wallets/eip155-1.jwt
# JWS payload: {"iss":"did:web:acef2002a…","vc":{"type":["VerifiableCredential","AgentWallet"],
# "credentialSubject":{"chain":"eip155:1","address":"0x9F2b...c41A","purpose":"treasury"}}}
Because the signing key is the same key DANE pins under _443._tcp.<name>, the wallet claim inherits DNSSEC's chain and is independently signed by a key a verifier already trusts for a different reason. Two unrelated proofs pointing at the same identity is exactly the redundancy Identity is built on: forging the wallet binding means forging the identity underneath it - DNSSEC, DANE, and reverse DNS all have to lie in agreement, not guessing which Discord post is real.
# With stock tools - fetch the credential and the did:web key, verify the JWS with any JOSE library
# (-k: the agent's TLS leaf is DANE-anchored, not WebPKI yet - the TLSA compare above IS the trust check)
curl -sk https://acef2002a323d40d4.t7af9242c44554e0f8e183ac8e6fbf645.agents.whisper.online/.well-known/did.json | jq '.assertionMethod, .verificationMethod'
curl -sk https://acef2002a323d40d4.t7af9242c44554e0f8e183ac8e6fbf645.agents.whisper.online/.well-known/wallets/eip155-1.jwt
# then, in any JOSE library: match verificationMethod[].id against assertionMethod[0] (never a fixed
# index), then jws.verify(credential, that entry's publicKeyJwk, algorithms=["ES256"])
# With Whisper - one call re-derives PTR/AAAA/TLSA/did:web from the IANA root, then folds the
# credential's ES256 signature check into that same chain walk - Whisper's API never in the trust path
whisper verify --trustless acef2002a323d40d4.t7af9242c44554e0f8e183ac8e6fbf645.agents.whisper.online
The complete publish-and-verify recipe - including which key signs, how to rotate it, and how a payer checks it in CI before a transfer - is its own page: Pin a wallet.
3. A signed output - provenance without a platform
The hardest version of this problem: "prove this document/commit/API response actually came from this agent, at this address, and hasn't been altered since." The same assertionMethod key does this too, through the mechanism Whisper ships a one-command wrapper for: whisper sign file produces a detached CMS (S/MIME) signature over the output, pinned by a DNSSEC-signed SMIMEA record, so a verifier resolves and checks the signer's exact key without a public CA. Combined with OpenTimestamps's Bitcoin anchoring, you additionally get when - a claim that can't be back-dated by the agent, its operator, or Whisper.
# With Whisper - sign, then verify keyless
whisper sign file report.md
whisper sign verify report.md --sig report.md.p7s
# With stock tools - the same signature, checked by hand: no JOSE library, just openssl + dig
openssl smime -verify -inform PEM -in report.md.p7s -content report.md -noverify -out /dev/null
openssl pkcs7 -in report.md.p7s -print_certs -out signer.crt
openssl x509 -in signer.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256
dig +dnssec +short SMIMEA d4f0bc5a29de06b510f9aa428f1eedba926012b591fef7a518e776a7._smimecert.acef2002a323d40d4.t7af9242c44554e0f8e183ac8e6fbf645.agents.whisper.online
# the openssl hash and the dig pin match, byte for byte - that comparison is the trust check
Full mechanism, a real captured run, and the raw-JWS alternative for tooling that wants JOSE instead of CMS, lives at Sign agent outputs.
Why "anything" isn't hyperbole
Once a name is provably yours and DNSSEC signs whatever you put under it, the set of things you can pin is bounded only by imagination and record-type ergonomics, not by anything Whisper has to build per-asset:
| Want to pin… | Record | Verifier does |
|---|---|---|
| A TLS/mTLS key | TLSA at _443._tcp.<name> |
SPKI-SHA256 compare, RFC 6698 |
| A wallet / payout address | ES256 JWS credential at /.well-known/wallets/<chain>.jwt |
fetch + JWS check vs the assertionMethod key, see Pin a wallet |
| An SSH host key | SSHFP at <name> (published automatically) |
RFC 4255, ssh -o VerifyHostKeyDNS=yes |
| A capability manifest / DID document | did:web doc at <name>/.well-known/did.json |
fetch + JWS check, see did:web |
| A signed output or dataset hash | detached CMS signature (whisper sign file) |
SMIMEA DANE pin, then openssl smime -verify, see Sign agent outputs |
| A PGP/age key for encrypted intake | OPENPGPKEY at <hash>._openpgpkey.<name> |
RFC 7929 |
None of these need a new Whisper feature to exist as a concept - SSHFP and OPENPGPKEY are RFCs that predate Whisper by over a decade, sitting unused because nobody had a name worth publishing them under. An agent's Whisper address gives it that name for free the moment it's provisioned:
CALL whisper.agents({op:'register', args:{label:'my-agent'}})
- one control-plane call (Control plane) allocates the /128, which derives the name, which is now a place you can publish anything DNSSEC can sign. Whisper ships the TLS pin and the did:web document automatically; wallets, output signatures, and anything else in the table above are yours to add at the same name, using the same key, checked the same keyless way.
Next
- Pin a wallet - the full publish-and-verify recipe for a payout address
- Sign agent outputs - provenance and non-repudiation for what an agent produces
- Identity - how the name is derived from the address and why the proofs stack