Hey everyone,
I’m Vedant (envoy1084.eth), I work at Namespace, where I like experimenting with ENS-related ideas.
Lately I’ve been working on an idea called Record Verification. I presented it during the ENS x AI call, where I learned that jkm.eth and Lighthouse Labs have also been working on the same problem and have a PoC live at atst.me
I thought other people might also be working on related projects, so I wanted to outline my ideas here to get feedback from the community.
Where the idea came from
The idea started with a small interaction in VS Code.
I was installing the Apollo GraphQL extension when VS Code showed me a trust prompt. One line stood out:
Apollo GraphQL has verified ownership of
www.apollographql.com.
That message does not guarantee that the extension is safe. It does not audit the code or promise that the publisher will never do anything malicious. But it does establish one useful fact: the extension publisher has proved a connection to the Apollo domain.
That small piece of evidence makes impersonation harder and gives the user more context before clicking “Trust Publisher & Install.”
It made me think about ENS.
ENS names can already publish websites, social accounts, payment addresses, content, application endpoints, and many other records:
text("url") = "https://example.com"
text("com.github") = "alice"
addr(60) = 0x3e708BBb834B769b1ef098946ed1FFdC17450d98
contenthash() = ipfs://bafy...
But what does one of these records actually prove?
The gap in ENS records today
An ENS resolver tells us what value has been set for a name. If url record for alice.eth returns https://example.com, we know that the record currently points there.
What we do not know is whether the controller of example.com has accepted that connection.
The same is true for other records:
- A name can publish someone else’s GitHub username.
- A name can copy someone else’s Bitcoin or Ethereum address.
- A name can point to a content identifier it did not publish.
This is not a flaw in ENS. Resolver records are intentionally flexible. They are statements made through the resolver, and in many cases that is exactly what we need.
A profile description, location, or header image does not necessarily need external verification. But some records are used for payments, account linking, agent discovery, application connections, and other actions where a stronger signal would be useful.
The question is:
Can we give applications an optional, standard way to verify the connection
between one ENS record and the external resource it points to?
That is the problem Record Verification is trying to solve.
The idea in one sentence
The current ENS authority approves one exact resolver record, and the external target provides its own proof for that same record.
Both sides are connected through a common claim. A client or SDK verifies the claim against live ENS state and method-specific evidence from the target.
There is no permanent onchain “verified” flag, and no new verification contract is required. Verification happens in wallets, apps, SDKs, indexers, or other clients that choose to use it.
How a record opts in
Verification is optional and configured one record at a time.
Suppose alice.eth has this URL record:
text("url") = "https://example.com/profile"
To opt that particular record into verification, the name also publishes a
companion text record:
text("verification[text][url]") = "ensrv1 a=1 m=https-origin.v1"
This small value is called a verification descriptor. It tells a verifier:
ensrv1: which version of the common Record Verification protocol to use;a=1: how to determine the current authority for this ENS name; andm=https-origin.v1: how the external target will prove control.
The descriptor does not contain the proof itself. It only tells the verifier which rules apply and, for methods that need it, where the proof can be found.
A walkthrough: verifying a URL record
Let’s follow the URL example from start to finish.
1. Alice publishes the URL
alice.eth → text("url") → https://example.com/profile
At this point, ENS only tells us that the resolver returns this URL. It does not yet prove that example.com accepts the association.
2. Alice enables verification for that record
text("verification[text][url]") = "ensrv1 a=1 m=https-origin.v1"
This selects the HTTPS-origin verification method.
3. The verifier determines the current ENS authority
“Authority” means the account that is allowed to approve verification for the exact ENS name.
The verifier calculates it from ENS state:
- For a normal unwrapped
.ethname, this is the Base Registrar registrant. - For a wrapped name, it is generally the exact Name Wrapper owner.
- Other exact ENS names use the Registry owner when the current authority profile supports them.
This distinction matters because the account allowed to update a resolver record is not always the owner of the name.
4. The authority signs one record-bound claim
The authority signs a claim containing the important parts of the relationship:
ENS name alice.eth
record text("url")
record value https://example.com/profile
current authority 0x1234...
method https-origin.v1
target https://example.com
issued at ...
valid until ...
The complete record value is included through a cryptographic hash. Changing the URL, record key, ENS name, authority, method, target, or expiry changes the signed claim.
This is important: the signature is not a general statement that “Alice owns example.com.” It approves one exact relationship for one exact live ENS record.
5. The website publishes the proof
For https-origin.v1, the verifier derives a deterministic proof location on
the URL’s origin:
https://example.com/.well-known/ens-record-verification/<proof-key>
The controller of example.com publishes the authority-signed proof at that location.
6. A client verifies everything against live state
The verifier then:
- reads the URL record and verification descriptor from the same ENS snapshot
- calculates the current authority for
alice.eth - derives the current record hash, HTTPS origin, and proof location
- fetches the proof from
example.com - checks that every claim field matches the live ENS record
- validates the authority signature; and
- checks the claim expiry and method freshness rules.
If every required check succeeds, the client can return:
{
"verified": true,
"verificationType": "control"
}
In plain language, that means:
The current authority for
alice.ethapproved this exact URL record, and the
controller ofhttps://example.compublished that approval at the required
location.
If the URL changes, the authority changes, the descriptor changes, the proof is removed, or the claim expires, a fresh verification will no longer pass.
The original URL record is still returned either way. Verification is an additional signal, not a replacement for ENS resolution.
What “verified” does and does not mean
The word “verified” can easily become broader than the evidence behind it, so the proposal intentionally gives it a narrow meaning.
For the URL example, it proves control of the HTTPS-origin publication capability for this exact ENS record.
It does not prove that:
- the website is safe
- its content is accurate
- the ENS name and domain have the same legal owner
- the target is free from phishing or malicious behavior, or
- ENS endorses either party.
Other verification methods
The current draft explores three method families:
| Method | What the target does | Status |
|---|---|---|
https-origin.v1 |
Publishes the proof at a deterministic HTTPS well-known path. | Concrete draft |
dns-txt.v1 |
Publishes the complete proof in a DNSSEC-authenticated TXT record. | Concrete draft |
account-signature.<profile>.v1 |
The account in an ENS address record signs evidence bound to the common claim. | Candidate profiles |
The same structure could later support social accounts, content-addressed resources, issuer attestations, or future resolver record types. Those methods should only be added when they can make a precise and testable claim.
Feedback
We have started to collaborate with Lighthouse on a more complete standard, and I would like feedback on my ideas above to help shape those conversations. I’d love to hear what you think:
- Has anyone attempted record-level verification before?
- Does this approach make sense?
- Is there anything missing?
The detailed protocol components, examples, method drafts, and open decisions are available here:
Read the Record Verification documentation
For faster discussion, you can also join the Record Verification Telegram group.
