Name Name System Specification v0.0.1
Editors
Authors
- Blaine Cook, Fission
- Irakli Gozalishvili, Protocol Labs (tbc)
- Chris Joel, Subconscious (tbc)
Depends On
- UCAN
- [WhoCAN]
0 Abstract
The Name Name System is a decentralized system for the storage and retrieval of mappings between verified names.
1 Introduction
If you never say your name out loud to anyone
They can never ever call you by it
- Regina Spektor, Better
1.1 Motivation
1.1.1 People need names.
People need names. Moreover, they have a fundamental right to a name, according to the UN Convention on the Rights of the Child. Having a name ensures our identity and individuality.
Names are the primary instrument with which we navigate the social world. Imagine, for a moment, what not having a name would entail; we wouldnāt be able to speak of our friends, family, or colleagues. Our ability to find people, even in extremely small social situations would be decimated. Weād have to resort to describing people: āthe friendly one, who works at the bakeryā, and hoping that enough context was present to convey our meaning. Of course, with enough specificity, āthe friendly one, who works at the bakeryā becomes a name; Amit Baker, for example. Even without names, names emerge.
Without names, weāre dehumanized, literally stripped of our identity. We become numbers: prisoners, without context and identified only in a way that is controlled by our captors. Itās not enough to have a name; itās essential to our humanity that we have names that we control. If someone else can change our name, then they can change us: who we are, at a relational level, is defined by our names.
1.1.2 People need names that work in online spaces.
Online, we lack the context of the real world, which means that we need to have names that carry some context. These can be petnames, names that we store in our own local address books, or names like email addresses that rely on a globally agreed and negotiated namespace (in the case of email, that namespace is the IANA-managed DNS system).
The challenge with these namespaces is that we become bound to them; an email address at gmail.com becomes a personās primary identifier across a whole range of internet services, but is āownedā by Google, not the individual. The approach in this specification seeks to provide an infrastructure that addresses all of the issues above, and restores agency to users whose names have been established in the context of enclosed corporate spaces.
All of the above needs to account for the fact that many people have multiple names, especially in online spaces. In real life, people change their legal name, they might go by a nickname, titles often stand in as names for one or more people (āIād like to speak to the managerā). Online, we tend to have one name per account; an email address, a different name on each social network we join, a name per work chat or document management context. Any system that deals with names online in a credible way must allow users to attest and understand the relationships between different names.
In the opposite direction, people have names and social contexts that they keep separate from eachother for very specific and intentional reasons. It should not be necessary for an individual to create linkages between all their names, or for an individual to disclose any of their names.
1.1.3 Things need names, too.
While not a question of human rights, we give things names, too.
Many of the challenges expressed above relating to peopleās names apply to names we hold for inanimate things, as well.
It would be ideal if a global naming system could support these kinds of names, too. Some examples are domain names and host names, ISBNs, software package names, and far too many others to list here.
1.1.4 Computers need keys.
While people need names, for secure operation, software requires cryptographic keys in order to positively identify actors in a system, and to correlate those actors across sessions. Historically, those keys take the form of passwords, but in decentralized contexts where even secured hashes of passwords cannot be shared, we need tools like asymmetric cryptography in order to provide this functionality.
It is important for any software system that bridges a usable āhuman nameā and a machine-oriented name or key to be able to transition securely between the two names; for example, from an email address to a public key.
1.1.5 Legacy systems need support.
The internet is built on a rich foundation of standards, many of which predate modern cryptographic tooling. Given a system that maps between names, it should be a goal to support non-human identifiers on both sides of the mapping. In particular, many existing naming systems do not transfer easily to a permissionless, offline, or peer-to-peer environment and would benefit from a naming approach that allows us to bridge that gap.
1.2 Non-Goals
While this specification strives for completeness, there are a number of use-cases that we donāt seek to support here.
1.2.1 Push or Peer-to-Peer Gossip Systems
NNS is designed as a lookup system. As such, it seeks to describe a mechanism to quickly go from a known name within a namespace to a key and published data about that name. Many systems may find it preferable to rely on names discovered by other means, including āgossipā protocols or other push mechanisms.
While it is entirely possible for WhoCANs to be transmitted directly from one peer to another, or distributed via a push mechanism, this specification does not attempt to describe any mechanisms to do so, beyond those necessary to support the functioning of a service-oriented network.
1.2.2 Global Consistency of Name Resolution
While NNSās design intends to provide an eventually consistent view of the world, it is likely impossible to do so perfectly and in a way that is acceptable to all uses and namespaces. Instead, if global consistency is required for a given name-to-key or name-to-data mapping, an external mechanism should be used.
1.3 Examples
The following are some potential examples of things that could be built with NNS.
n.b. that these have wildly varying degrees of difficulty, and inclusion here is not intended to imply that the example should be implemented, only that it could be.
- Pointing from a name in one namespace (e.g., dns/email) to another (e.g. a petname, or a name within a pet-namespace)
- Mapping from an email address to a public key
- Mapping from an email address to profile information (e.g., ActivityPub endpoint)
- Mapping from a phone number to an email address
- Mapping from a domain name to an WNFS path.
- Mapping from one postal address to another, or an email address to a postal address
- Pointing from an HTTPS URL to an IPFS-hosted version of same without Signed HTTP Exchange
- Securely providing DNS records with low latency.
1.4. Requirements
1.4.1 Permissionless
Anyone should be able to add a name to the system provided that:
- The name is verifiable
- The name is verified
It should be possible to host a name for which one doesnāt control the authority (i.e., anyone in the network can host/mirror/provide any subset of names)
1.4.2 Delegatable Management
It should be possible to either (1) self-host a name or (2) pay someone
to host a name on your behalf.
1.4.3 Performance
DNS-level performance is probably āgood enoughā; Google reports 300-400 ms real
average latency (accounting for failed responses), 130 ms for servers that
respond.
A target of sub-100 ms latency over the public internet for uncached reads seems like a reasonable goal, because why not try to do better than DNS?
For writes, high performance isnāt critical. Individual WhoCANs can define consistency guarantees at the level of verification, but e.g. DNS as-is doesnāt provide any information about write speed, as there is no common interface for writing names into DNS.
1.4.4 Scalability
The system should work in online and offline contexts, or within a partitioned network. The operational complexity of the system should remain constant regardless of the scale of the deployed system. Similarly, the performance characteristics should be constrained only by the inherent latency of the network itās running on (speed of light and all that).
1.4.5 Resilience
The system should be resilient against known malicious attacks (see: Security Considerations).
While byzantine fault tolerance is an ideal goal, global consistency is considered unnecessary for the system, since there are opportunities within the WhoCAN system to account for inconsistency at the network layer.
However, the network is designed in such a way as to provide reliable and eventually-consistent reads within a short timeframe after new writes. The network should be monitored for overall consistency, especially the latency necessary to attain a consistent state after writes, and adjusted as necessary to provide an acceptable level of service.
1.4.6 Backwards Compatibility
A system thatās backwards-compatible with existing name lookup systems,
where one exists for the namespace.
2. NNS Protocol
2.1 API Methods
The API methods below are exposed as HTTPS endpoints. See [NNS.dht] for the method to discover and navigate endpoints.
n.b. that all requests MUST be made over HTTPS, but the security of the system does not depend on HTTPS validation of the HTTPS certificate.
2.1.1 POST /set
2.1.1.1 Arguments
Arguments are provided using an application/json
-encoded body.
!!! NOTE: should this be CBOR encoded, or other?
name
: A name.
value
: A WhoCAN, verifiable by the network.
2.1.1.2 Authorization
Requests MAY optionally include an Authorization header, which may be desirable to prevent nodes from handling large volumes of invalid anonymous set
requests. Nodes SHOULD use UCAN bearer tokens to authenticate users, as described in (link to appropriate spec).
The method for establishing access to a node (e.g., payment) is out of scope for this specification.
2.1.1.3 Processing
An NNS node accepting a request such as the one above MUST validate the WhoCAN before accepting it. In order to do this, the node MUST support the did
method used in the iss
field.
The method used to validate the WhoCAN and establish the validity of the delegation is describe in WhoCAN, and the normative text for the appropriate did
method. A longer treatment of verification for the purposes of NNS is included below in S2.x
After validating the request, the node SHOULD propagate the name via the mechanism described in 2.2, NNS.dht.
(aside: the long-term expectation is that validation can be outsourced to a trusted wasm blob; a parent one for WhoCANs, and sub-delegates for verifying did
methods. Pointers to these methods could be stored in an NNS namespace; e.g. āwasmpkg:code.fission.codes/whocan:verifyā and āwasmpkg:code.fission.codes/did:mailto:verifyā) to ensure the ability to upgrade code in future.
2.1.1.4 Response
The response code MUST be one of:
- 201 Created, if the request was successfully validated and stored.
- 202 Accepted, if the request was valid but the WhoCAN was not validated before the node returns an HTTP response.
- 400 Bad Request, in case of a malformed request or invalid WhoCAN
- 401 Unauthorized, if the request is does not have an acceptable Authorization (per 2.1.1.4)
- 409 Conflict, if the WhoCAN is valid but is inconsistent with prior WhoCANs (out of scope for this specification)
- 429 Too Many Requests, if the request is rate-limited.
- Any valid HTTP 500 response in the event of a server error.
The response body SHOULD provide descriptive information regarding the status of the request.
2.1.1.5 Example
POST /set HTTP/1.1
Host: nns-node.net
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "alice@example.com",
"value": "{
iss: "did:mailto:alice@web.mail",
aud: "did:key:zAgent",
att: [{ can: "ucan/sign", with: "*" }],
prf: [{ DKIM Proof }],
fct: [{ "profile": "ipfs://$CID" }]
exp: future,
sig: "..."
}"
}
2.1.2.6 Privacy Considerations
It is not possible to both verify the WhoCAN and maintain privacy of the name. Names shared on the NNS network will be readable by any peer systems.
It is, however, possible to host names on the DHT without disclosing names to other nodes (see GET method 2.1.2.1), with the caveat that these names will not be replicated by other nodes, which may have an impact on latency to resolve these names.
It may be possible to verify WhoCAN names using homomorphic encryption in the future, in which case names could be shared in a fully encrypted form (with the name as the encryption key, and the name shared as a hash of the name). Alternatively, a scheme involving trusted notaries could be adopted; however, that is out of scope for this document.
2.1.2 GET /{name}
2.1.2.1 Arguments
The name
argument is the only argument.
!!! NOTE: This should be two arguments: the hash of the name, not the name itself, and some routing hints, since the node doesnāt necessarily know the name, and in order for the DHT to be performant, we need hierarchical routing. Iāve left this as just name
for now for clarity, but please assume that the request is intended to preserve query privacy.
2.1.1.2 Authorization
Requests MAY optionally include an Authorization header, which may be desirable to prevent nodes from handling large volumes of anonymous get
requests. Nodes SHOULD use UCAN bearer tokens to authenticate users, as described in (link to appropriate spec).
The method for establishing access to a node (e.g., payment) is out of scope for this specification.
2.1.2.2 Response
2.1.2.2.1 Successful Response
If the server has value(s) for the requested name, the response MUST be a {encoding}-encoded encrypted JSON (CBOR?) list of the original WhoCAN(s) as submitted to the network. The response MUST also include a corresponding list of notarizing assertions, signed by the nodeās public key in UCAN format, attesting that the node validated the WhoCAN(s) provided in the response.
(note that the server can pre-compute the attestations and store them alongside the WhoCANs; the expectation is that returning these attestations at GET time adds negligible overhead, and provides the ability to censure servers that provide invalid responses)
The payload MUST be encrypted using (x) with a symmetric key that is the original, un-hashed value of the name.
2.1.2.2.2 Indeterminate Response
If the server does not have value(s) fro the requested name, it can choose one of two options: it MAY act as a proxy, and traverse the DHT to find and return the response for the client, or it MAY return an appropriate 3xx HTTP response to direct the client to a different node that might have more information about the name.
2.1.2.2.3 Cached Response
In the event that the client provided valid HTTP cache headers, the server MAY respond with an HTTP 304 response, indicating that the name is not modified, and omit the response body.
2.1.2.2.4 Error Response
In the event of a server error or malformed GET request, the server SHOULD respond with a valid HTTP 4xx or 5xx response code. In either case, the format of the body is undefined, but should provide useful debugging information where possible.
2.1.3 Intentionally not included: /revoke
A revoke
method for names has not been defined, since calling set
in a way that invalidates old WhoCANs is probably better than a dedicated revoke
method, because revoke
is less likely to be consistent.
!!! Note: this may be a mistake. Thoughts welcomed!
2.2. NNS.dht
!!!
nb. this section is a work in progress and makes unsubstantiated claims; proceed with skepticism and caution. Feedback or thoughts on how to improve the DHT proposal are extremely welcome.
!!!
Due to the latency and verification requirements of the NNS system, there is no acceptable off-the-shelf DHT. However, many of the desired properties can be achieved with relatively minor tweaks to existing approaches.
- Kademlia-based, but maybe it should be MDHT or similar?
- Prefix bloom filter
- nodeid: [support] [prefix] [nodeid]
- Nodes MUST set the bits for resolution protocols they support in the
āsupportā section of the bloom filter/node id in order to avoid routing
requests for storage/retrieval to nodes that do not support that scheme. - Nodes SHOULD set the bits for the prefix they wish to host in the
āprefixā section of the bloom filter/node id in order to decrease routing
path distance. - Key hash encoding:
- calculate hash of key (e.g.,
did:mailto:blaine@fission.codes
) - prefix with:
- a bloom filter including the verification method of the key (
did:mailto
) - plus prefix of address added to a similar bloom filter (
codes.fission
)
- a bloom filter including the verification method of the key (
- calculate hash of key (e.g.,
- perform normal kademlia routing, with optional cached routes to nodes that match
- first the support filter
- then the prefix filter
2.2.1. Name Sharing / Distribution
2.2.2. Routing
2.2.3. Bootstrapping
2.2.x. ???
What else am I missing here?
2.2.x Caching
Edge nodes SHOULD provide a caching layer to prevent repeated queries to the wider DHT. Nodes MUST obey TTL information on the WhoCANs (if present) and remove any expired names from their cache.
2.2.x Updates
Due to the complexity of implementing push updates across a very large network in an efficient way, this specification does not include a gossip protocol approach to sharing updates. However, it may be advantageous for certain use-cases to enable push updates to listeners. There are a number of viable approaches, such as EBT, but this functionality would warrant further research (and may be unnecessary if the real-world latency and scalability of the DHT protocol are acceptable).
2.4. Validation
- The payload must be a verifiable delegation UCAN (WhoCAN) that delegates
a name to a did:key and an optional URL. - The content at the optional URL should be in (provisionally) webfinger
profile format. - For privacy, it should be possible for a node to host a name that is not public, and whose data is not intended to be public. In order to do this, the node can require authentication on Get() requests (in the form of a UCAN) or provide the response for a name as an encrypted bundle. In this case, the name will not be stored by peers since it is not verifiable (barring advances in homomorphic encryption or in the case of names whose governing authority has signed the encrypted WhoCAN in a wrapping WhoCAN).
3. Terminology
3.1 Name
A name is any unicode string that has a corresponding DID method (i.e., there is a way to verify ownership of the DID)
3.2 WhoCAN
A WhoCAN is a UCAN that delegates from one did to another. Compare with Verifiable Credentials.
4. Security Considerations
4.1 Privacy Considerations
4.1.1 Enumeration of the Keyspace
The names stored in NNS must not be trivially enumerable. Obviously, if someone already has the name, they should be able to query for it, but building indexes of names shouldnāt be possible by scanning NNS itself. Preventing the enumeration of names using mechanisms unrelated to NNS is outside the scope of this document.
4.1.2 Encrypted Data
It should be possible to support encrypted or local-only storage of WhoCANs in order to support names that are not publicly disclosed.
4.2 Verification of Names
While the nodes MUST validate the WhoCANs that they store, clients must also verify the WhoCANs (or delegate to nodes that they trust to do the verification for them). The protocol design mitigates against malicious or defective nodes by using local consensus measures in order to ensure good performance and reliability across the network, but cannot wholly prevent unverified data being introduced.
4.3 Hijacking Names
This is a thing that would be bad.
4.4 Denial-of-Service Attacks
4.4.1 DHT flooding attacks
Creating many nodes with intentionally malicious behaviour in order to prevent legitimate nodes from providing responses to queries.
4.4.2 DDOS attacks
Attacks created by large numbers of outside actors sending large numbers of spurious requests to the network in order to overwhelm the nodes in the system. Possible by flooding with either Get() requests or Set() requests (even with invalid records). Probably necessary to provide mitigations.
4.5 Malformed Input Attacks
Attacks as a result of using malformed input, either in Get() or Set() methods that causes errors or exploits in the nodes.
5. Related Work and Prior Art
5.1 Prior Art
5.1.1 DNS
DNS is great, but doesnāt handle anything that isnāt a domain name, has a single point of authority (not a bad thing! Just not great for every use case), and doesnāt have a permissionless way to do scoped/local names (i.e., setting up an intranet DNS server requires a lot of coordination).
5.1.2 GNS: GNU Name System
Pretty complicated, only does domains. Positioned as a replacement for DNS servers, not much else.
5.1.3 Webfinger
depended on adoption by incumbents with no motivation to support (or, worse, motivation not to support). Goals were well understood by a core set of contributors, poorly communicated.
5.1.4 Webfist
Very similar to Webfingerās approach, iteration on Webfinger; built as a hack day project, was never iterated on. Terrible name.
5.1.5 did:orb and sidetree
Not dissimilar to NNSās goals, but does not provide a globally uniform lookup mechanism.
5.1.6 IPNS
5.1.7 DNSLink
5.1.8 PGP WoT / Open Rings
Assumed email insecure, bootstrap via incredibly complicated social ritual, extremely high cost associated with losing key. Also: slow, poor tooling. Vastly too early. Discovery
5.1.9 XRI
Profiteering. Centralized. Schema-focused (XML dayze) vs action.
5.1.10 Keybase
centralized, bootstrapped identity from centralized systems ā no path to true autonomy. Sold out.
5.1.11 ENS
Parallel system to DNS, fundamentally focused on monetizing names (see also XRI), with a crypto lens so theoretically decentralized, but fundamentally too expensive with no credible story for reducing costs. Significant community issues especially with regards to trust and safety for LGBTQIA+ individuals and the founders/DAO/token holders.
5.1.12 Keyoxide
Decentralized replacement for Keybase. Uses archaic PGP keys, no global/decentralized name lookup system. They point to the possibility, but donāt describe a mechanism.
6. Acknowledgements
- Brooklyn Zelenka
- Zeeshan Lakhani - DHT help
- Bill Thompson - name
- Mikael Rogers - http interface
7. References
7.1 Normative References
- WhoCAN
- UCAN
- Kademlia
- Webfinger Profiles
7.2 Informative References
7.2.1 DHT Research
- DHT-bsed Communications Survey: Architectures and Use Cases, Yahya Hassanzadeh-Nazarabadi, 2021
- T-DHT: Topology Based Distributed Hash-Tables, O. Landsiedel, 2005
- Locality Aware Skip Graph, Yahya Hassanzadeh-Nazarabadi, 2015
- Decentralized utility- and locality-aware replication for heterogeneous DHT-based P2P cloud storage systems, Yahya Hassanzadeh-Nazarabadi, 2019
- LAND: Locality Aware Networks for Distributed Hash Tables, Ittai Abraham, 2003
- Kademlia, Petar Maymounkov, 2002
- k-rAC ā a Fine-Grained k-Resilient Access Control Scheme for
Distributed Hash Tables, Olga Kieselmann, 2016 - Host Identity Protocol Distributed Hash Table Interface, J. Ahrenholz, 2012
- Open Problems: Routing at Scale
- A Note on Routing Scalability in Named Data Networking, Yu Zhang, 2019a
- On-demand routing for scalable name-based forwarding, Onur Ascigil, 2018
- MDHT: a hierarchical name resolution service for information-centric networks, Matteo DāAmbrosio, 2011
- DECENT: A decentralized architecture for enforcing privacy in online social networks, Sonia Jahid, 2012
- Notes on Privacy Preserving DHTs
7.1.2 Other Related Distributed Systems Research
- How to Have your Causality and Wall Clocks, Too, Jon Moore, 2015
8. FAQ
13.1 Is this a standard?
No. I donāt write standards. Itās just a thing we think is useful, and others are welcome to use it and contribute proposed improvements and code.
9. Annexe
9.1 Other Widely-Deployed and Successful Global Addressing Systems
9.1.1 Postal Addressing
Global, universal, decentralized, not dependent on technology. Trust-based, but third parties provide secure/authenticated delivery. Addresses are effectively opaque to the end user (esp. across international boundaries). Finds a balance between strict naming systems (postal codes) and pseudo-petnames (e.g., letters addressed to Blaine, Slocan Lake, BC will probably find their way to me). Addresses are globally unique with sufficient (optional) specificity.
9.1.2 Phone network
Global, universal, decentralized. Standardized and not petname-based; routing network is encoded in the address. Allows for local abbreviations by omitting parent levels of routing, at the cost of added complexity (e.g., omitting +1 in North America for local numbers, or the
+44 (0) 12 345 6001
notation in Europe, which means: āomit the 0 for dialling from an international extension, omit the +44 and use the 0 prefix for dialling within the +44 country code.ā)
People manage, only barely ā increased international communication plus ubiquitous contact stores on phones means that memorization is no longer necessary and we default instead to full expanded form. Deeply insecure by virtue of the legacy SS7 network having no meaningful protections aside from contractual. Uneven application of standards across international boundaries (whither art thou, callerid?!)
Notably, phone number addressing has been re-used by Signal and WhatsApp, with some advantages (phone-local bootstrapping of numbers in the contacts db) and significant disadvantages (involuntary disclosure of the existence of accounts [not necessarily a problem], inability to switch accounts/use burner accounts easily, security is fundamentally linked to telco security (lol) and I donāt care what anyone says about that because key rotation warnings will always be ignored)
9.1.3 DNS
9.1.4 Email
Global, universal, decentralized, standardized. Main issue is that identities are not secure except as validated by domain owner (āreset password linkā or OIDC). Primary identifier in use by virtually every online system. Significant identity lock-in, few motivations for providers (Google, Microsoft, Yahoo, AOL, Universities, Apple in that order *pull stats) to build decentralized alternatives. Increasing spam mitigation means itās increasingly difficult to self-host, diminishing decentralization afforded by DNS. Probably a lot more to say here.
9.1.5 Centralized Global Systems (Monopolies)
Twitter/Facebook/Instagram/TikTok
Centralized identifiers, notarized by large corporations. Twitter/instagram/tiktok primarily āusernameā based, allows for multiple identities. Globally unique, within a single namespace. Significant first-mover advantage to naming. Content-based discovery of identities, depends on publicity (i.e., not good for private accounts); this applies doubly-so for Facebook. No credible path to decentralization aside from adopting DNS-style scheme (e.g., blaine@twitter.com)
9.2 Petnames
Aside: petnames. Very useful for local-first/personal systems where bootstrapping the network can happen in-person / via direct device-to-device negotiation. Not useful for async/remote bootstrapping of networks.
Christine Lemmer-Webberās writeup on petnames is extremely relevant here. In the context of that paper, NNS can be understood as an āEdge Nameā lookup registry. Any edge name that is able to verify a name within its āpetnamespaceā can be included in the NNS system.
10. Open Questions
Population Protocols
Once we have the DHT, how do we create local swarms so that servers that have opted in to serve names are guaranteed to be given the opportunity if no-one else can do it?
Notarization
This is more a question for WhoCAN, but notarization is likely to be an important aspect of all this.
Responses
Should the responses be signed?