sRFC-35 - Address/Domain Association Specification

sRFC-35 - Address/Domain Association Specification

Summary

Solana addresses can be publicly linked to domain names using DNS TXT records or a well-known file. This allows for applications and services (like wallets, exchanges, and infrastructure providers) to easily validate if a company is associated (or denounce associations) with a token, program, or other Solana address that may be using their trademarks.

Background

As more companies and brands interact with permissionless blockchains (like Solana), having simple mechanisms for them to publicly associate (or denounce association) with onchain assets will enable verifiable trust for these groups and the broader Solana ecosystem.

Utilizing DNS TXT records or a well-known file on a website, domain administrators can associate blockchain addresses for tokens, programs (smart contracts), or other Solana addresses. This allows other companies and products to validate the original company’s connection to said Solana address.

Example use cases:

  • A brand issues a Solana token with their website listed in the token’s metadata. They add a DNS record to store the token’s Mint address on their DNS records. Popular token list providers, like Jupiter and CoinGecko, can fetch, parse, and validate the token in question was created by the brand. Enabling their verification processes to be more efficient while also enabling the token issuer to get easier access to liquidity at launch.
  • A company deploys a Solana program (smart contract) onchain. The company adds the DNS record associating the program address to their website. The program’s security.txt information includes the company’s contact information and website for security researchers to responsibly report vulnerabilities.

Note: This practice of domain verification through DNS records is already a common practice in the broader tech industry. For example, connecting your website to the Google Cloud Console or verifying domain ownership for various AWS products.

Specification

To associate a Solana address with a domain name, the domain administrator should create a DNS TXT record on their registrar or a solana.txt file on their website’s .well-known directory to store the “association records” using any of the applicable well-known tags listed below.

Association through DNS TXT records

(most recommended)

Domain administrators can add one or many DNS TXT records, each storing a single “association record”.

Note: DNS TXT records have a few limitations that are not expected to be an issue for this specification, but worth noting in the event they are. If either of these are a concern, see solana.txt below for another option:

  • TXT records are limited to 255 characters, per the DNS spec. A typical “association record” per this spec should normally be a max of <80 characters.
  • Some domain registrars and platforms, like Google, recommend no more than 49 TXT records due to this being the max supported by domains themselves.

Association through the solana.txt file

Due to company policy or technical limitations, it is possible that some administrators are unable to create additional DNS TXT records for their domain. In such cases, address association can be accomplished by creating a solana.txt file and storing it in the .well-known directory (see RFC-8615).

For example:

  • Domain: example.com
  • Location of the association file: example.com/.well-known/solana.txt

The solana.txt file should only store one “association record” per line to allow efficient parsing by record validators.

Note: It is highly recommended that administrators allow frontend applications to access their solana.txt by setting correct CORS headers. This will help ensure anyone that would like to can validate the address/domain association.

Association records

A single entry in the DNS TXT or line in the solana.txt file is called an “association record”.

Each entry should store the UTF-8 string of a space separated list of tag-value pairs (using the well-known tags supported below).

Each association record should contain a single “address tag” and a single Solana address as a base58 encoded string, followed by any additional qualifier tag-value pairs (deny, allow, network, etc).

If a domain or website wants to deny all association with all Solana addresses (tokens, programs, etc), they can create add a single “deny all” association record of solana-address=denyall. This special record takes precedence over all other association records.

Well-known tags

Each association record should contain a single “address tag” that best describes the purpose of the Solana address

  • solana-mint-address - associates a token’s Mint address to the domain.
  • solana-program-address - associates a program address to the domain.
  • solana-address - associates any other Solana address with a domain (such as a verified signer, program deployer, or other authority).

In addition to the blockchain specific tags above, the following generic tags (qualifiers) are also supported to add amplifying information about the associated relationship:

  • deny (optional) - Explicitly deny the association of the address with the domain.
  • allow (optional) - Explicitly allow the association of the address with the domain.
  • network (optional) - Define the Solana or SVM network the address is used on. This value can be either a Solana network moniker (mainnet, devnet, testnet) or the genesis hash of a SVM network, as a base58 string. If not set, defaults to Solana mainnet.

Qualifier notes:

  • The value of a qualifier should be the case-insensitive string or numeric equivalent for a boolean value (i.e. allow=true and allow=1 set “allow” to the boolean true)
  • Records should not contain both allow and deny
  • When no allow or deny is set, defaults to allow=true signifying the domain is in fact associated with the address.

So an association record would resemble the following examples:

# token on mainnet
solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
# token on devnet
solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v allow=1 network=devnet
# generic address
solana-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v deny=1 network=devnet

solana-mint-address

This association record’s “address tag”-value pair should be used to store a token’s Mint address as a base58 string:

  • To allow association:
    • solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
  • To deny association:
    • solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v deny=1

Example: To associate the USDC token with a domain, create an association record with a value of:

solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

Which is also the same as:

  • solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v allow=true
  • solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v allow=1
  • solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v network=mainnet allow=1

To deny association of a token’s mint:

solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v deny=1

Which is also the same as:

  • solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v deny=true
  • solana-mint-address=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v network=mainnet deny=true

solana-program-address

This association record’s “address tag”-value pair should be used to store a program’s address as a base58 string:

  • To allow association:
    • solana-program-address=SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu
  • To deny association:
    • solana-program-address=SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu deny=1

solana-address

This association record’s “address tag”-value pair should be used to store any address as a base58 string. This is considered a fallback address tag and should only be used when the other, more explicit tags do not fit the address’ use case.

  • To allow association:
    • solana-address=nicktrLHhYzLmoVbuZQzHUTicd2sfP571orwo9jfc8c
  • To deny association:
    • solana-address=nicktrLHhYzLmoVbuZQzHUTicd2sfP571orwo9jfc8c deny=1

Linking a domain within onchain information

If there is a domain referenced in onchain-linked data, including the contents of referenced offchain JSON files, an association check should be performed to verify a connection to the brand/company’s linked domain.

When wallets, token lists, block explorers, and other applications are presenting information about onchain data (i.e. url for a token’s image, primary media file, or url for its additional offchain metadata file), they should also present the address/domain association status when available.

These “association validators” can poll the DNS records (or solana.txt file) for the domain in question and validate if the domain and onchain information point to each other. If they do and are in the “allow” state, the ecosystem can consider these associated. Otherwise, not-associated and handled as such.

Listed below are some of the most commonly used standards where domains are referenced in onchain-linked data. As future metadata standards develop and are adopted, they should also consider and adopt similar pattern. And therefore be supported by this specification.

  • Metaplex’s Fungible and Non-fungible asset standards - contain support for the image, external_url, and animation_url fields
  • SPL Token metadata interface - contain support for the a uri field that links to offchain metadata file, normally as a JSON format. This JSON file commonly follows one of Metaplex’s standards.
  • security.txt - contain the project_url field and other domain related fields

Security considerations

Permissioned access. Modifying DNS records or uploading the solana.txt file require permissioned access to a domain and its resources. If an attacker was able to gain permissioned access, they could modify the association records. Due to this not being an attack vector being specific to this specification, it is consider out of scope. Domain administrators should ensue they have strong security practices to prevent this.

Homograph attacks. With the use of domain names to validate if an addresses is associated, attackers will likely attempt to perform these letter substitution attacks on domains/users.

  • Since the address/domain association checks will be performed by code and automated systems, so it is not a concern there.
  • However, when the domain names are presented to users they could become fooled by the letter substitutions. As such, applications should be diligent in helping to minimize/prevent fake domains by performing mitigation steps. See examples here.

DNS cache poisoning. Attackers could attempt to poison the DNS cache for servers and users attempting to get the association records from a domain. If an attacker is successful in this type of attack, association validators could be fooled into validation the attacker-inserted association. Resulting in applications and users falsely thinking the attacker’s address is truly associated with the domain.

  • DNS cache poisoning can be prevented by domain administrators enabling and using DNSSEC. It is strongly recommend that administrators enable DNSSEC and that automated validation processes check for DNSSEC enabled domains.
6 Likes

This is awesome! Voicing my support as this initiative will not only significantly help companies who are on-chain to be verified, but also prevent companies who are purely off-chain from becoming the target of nuisance crypto scams.

4 Likes

Love the idea. If we go with the solana.txt file we could even think of including the actions.json for blinks in there

6 Likes

I think this would need some additional record akin to DS records that contains a signature from the authority (wallet / update).

Without this, a nefarious website could link any program/address to their domain.

If client implementations utilize sRFC-35 for sensitive or verification purposes this could lead to loss of integrity in the security sense and make for a bad time.

6 Likes
  1. You will lose 90% of companies as soon as they have to learn to deploy a Solana program.
  2. I agree with @wedtm that DNS doesn’t really seem like the best place for this.

You really want some sort of on-chain attestation, most of which can be built with existing tools like Civic KYC, Core Autograph plugins, Bonfida domains, Solana ID, etc. I think it makes the most sense to create a spec with existing partners instead of building a new tool.

2 Likes

Edit to 1, maybe I misread and the program deploy only relates to associated program IDs.

Addendum, this is already possible with mints using the Verified Creators array on Token Metadata. A DAO or KYC wallet can sign to verify themselves as a creator for the token/NFT mint.

The other DNS record types are interesting :thinking:

I’m not sure I agree with your point about nefarious websites linking to real tokens. Since the token would also have to link back to the website.
Both have to point at each other for the association to be valid. Same for programs.

For a generic address, this might apply though.

1 Like

How does a TM verified creator help here? It ensures the Singer was capable of singing. But it in no way ensure the signer is also actually in control of any of the domains listed in the metadata fields

Program deploys applied to the metadata already stored in the programs info (like security txt)

If a company does deploy a custom program, they lost their domain in the security txt metadata, then update their domain to effectively acknowledge that they own the program.

If they don’t want to deploy a program, they don’t have to

1 Like

Verified creator is a two way handshake. The token authority must add the creator to the array (e.g. Metaplex DAO wallet gets added to MPLX) and the added creator must also sign (Metaplex DAO wallet signs the metadata). Bidirectional attestation.

I really like this idea, it seems like the only real way for a Web2 company to verify an on-chain identity.

Using a Solana-based protocol for verification doesn’t actually solve the problem since there’s no guarantee the company is who they claim to be. It just shifts the issue somewhere else.

It’s also the only way a company can actually deny being associated with anything on-chain. Asking them to sign a Solana transaction to prove they aren’t on Solana doesn’t seem to make much sense.

2 Likes

Attack scenario:

  • I can vanity a token address that matches the first and last N characters of a popular token to avoid the common pattern of middle-out truncation.
  • link it to a scam site, and implement sRFC-35 with only the suggested.
  • start a common spam campaign with a 1-2% success rate across 100k impressions

This doesn’t even begin to go down the rabbit hole of orgs that do wildcard entries to places like vercel, allowing anyone to create a new vercel site with scamsite.legitcompany.com.

We could probably role-play a few more scenarios, but the real benefit of the signature is that it allows cryptographic validation by machines. This would enable something like the green lock / address bar for extended validation TLS certificates.

THIS would incrase user experience massively as wallets and clients could use this bi-directional verification as a first line of defense in filters.

If the DNS signature is from the token deployer, that’s a cryptographic prove that the same entity controls access to both.

1 Like

This still only connects addresses to other addresses. It doesn’t solve the same issue that this sRFC addresses. It does nothing in the way of attesting offchain info (like a domain name) is validated or not. Its just two addresses connecting together

Re: your attack scenario

The existing ecosystem trust assumptions still exist. The only benefit of sRFC-35 is that if multiple tokens are created and point to the same domain, you can tell which is the one true token. This spec does not technically improve anywhere else (yet). Even with your signature idea, the same attack scenario still exists.

They are issuing their scam token and association on their scam site. They could add the signature into their record. Signature does not prevent this, it just validates that the scam token minter updated the DNS entry.

Therefore, what is the actual benefit of putting a signature in the association record? I can only think of it negating scenarios where people try to associate with a token they did not issue (which is still useful). So I’m totally game to add something into the spec here for it. Do you have a suggestion on how it should be added?

My initial thought is adding the signature into the association record so it could be verified by others. The message to be signed should a standard format including the domain itself and the address and maybe a timestamp of some sort?

For tokens, token issuer signing makes sense but you would also have to go back in chain history for that (since mint authority could have changed or been removed). Mint authority could be used but what if it is removed? Same for upgrade authority.

For programs, upgrade authority could be used to sign but it can also be removed. So what then?

For generic addresses, they could sign their own message. So I guess that works

1 Like
Signature does not prevent this, it just validates that the scam token minter updated the DNS entry.

The signature allows easy denouncement. Any app/dapp can automatically invalidate any token that claims to be from a domain that:

  1. Has a valid signature in it’s DNS, and;
  2. doesn’t have a signature for the token in question.

I do think that tokens are the most problematic like you’ve pointed out since any link could be renounced later.

Potentially the spec could specify that only the most recent authority is considered valid unless it’s completely renounced and then the last is considered authoritative?

That doesn’t really solve for the opposite where a domain might eventually change ownership as well.

I have published an IETF Internet Draft for mapping that we hope will become an internet standard.

Would primarily use the WALLET RRType and DNSSec to secure the addresses.

Would like to see if we can unify this into an RFC to everyones benefit.

Just read through the IETF draft you proposed. It looks like we have a lot of similar ideas on this idea.

After a first read, your proposal only allows associating base chain coins (e.g. BTC, SOL, etc) to a domain, but does not really allow more fine grain association of tokens created within the chain’s themself. This would be fine for the chains that do not really support additional tokens being created by users of the network (like bitcoin), but for smart contract chains like Solana and Ethereum, your proposal does not really support people/companies associating other tokens to their domain. Example: Circle’s USDC on Solana and/or Ethereum or Paypal’s PYUSD on Solana

In addition to wallet addresses that can hold the base chain token’s, addresses can be used for other purposes aside from holding tokens. Solana programs also have a base58 encoded address similar to a regular “wallet address”. Same for Ethereum smart contract addresses.

How do you propose unifying our proposals? Including to ensure we can cover other types of address that are not just the base layer coin?

@seeker accidentally didn’t reply, so tagging you here :slight_smile: