NNS - The Name Name System

While I want it to be possible, I gotta admit I don’t fully see how DKIM will work in practice.

My understanding is that

  • not all email domains support DKIM - it’s it’s own spec, not required by email itself
  • DKIM keys are rotated no less frequently than once every six months. Sometimes 3 months. Nothing stopping a domain from doing it every day
  • DKIM doesn’t specify a way to look up old keys (e.g. to validate old signatures like one in the UCAN proof above)

It seems like this would mean that a dkim-verified name becomes unverifiable as soon as the email provider rotates the keys, so NNS nodes would stop hosting the no-longer-verified name.

If I was using NNS to point from my email address to a CID, that could stop working at any time. And the name controller might not know. Things would just stop working until the user:

  1. found out their names stop resolving
  2. created a new DKIM proof (
  3. use some app to embed this DKIM proof along with all the name values (gotta keep track of what those old values were…) in a new UCAN and rebroadcast

I can’t quite tell if the goal here is to have DKIM-verifiability be a key part of NNS, but unless that’s true, it might be good to decouple them.

Names can be anything! All DIDs are in scope, or any name that’s verifiable. So, a petname wouldn’t be valid unless there were a pointer to the petnamespace and a way to verify that the name was valid within that namespace (for example, it’s possible to verify Twitter names by tweeting a link containing the delegate key and using the tweet URL as a way to verify the name (in this case, the name could be simply “@bengo” if verifiers decided to treat the @ prefix as a Twitter petname, or the name could be twitter:bengo or https://twitter.com/bengo or bengo@twitter.com or did:twitter:bengo.

The last one probably makes the most sense in the context of NNS, since the thing that DIDs get us here is a verification method (at least, in theory :sweat_smile:)

DKIM’s 100% a hack. Better would be support for an ACME-style key exchange or another formal method. That said, re the specific concerns:

  • no domain level support: soz, your email address sucks and you should get a new one, not least because you can’t send email that doesn’t get immediately ring-filed.
  • short-lived dkim keys: I don’t know policy here, but rotation is probably infrequent because the motivation for rotation is protection against hacking. If your dkim keys have been hacked, wow are you in trouble. Don’t let that happen. :sweat_smile::face_with_peeking_eye:
  • short life/no history of dkim keys: this is solvable (both online and off) with a Certificate Transparency chain.

But, more generally, NNS’s intended scope is much wider than dkim-based delegation from email addresses. (And ultimately it would be way better for a whole host of reasons for email/domain providers to give a more formal method of externally verifiable verification than dkim).

I believe that this DID is invalid according to the syntax in did-core, which disallows @ in method-specific-id. It allows a pct-encoded as %40

related issue: accounts spec uses dids with invalid syntax ('@' char) · Issue #28 · web3-storage/specs · GitHub

:+1: Good to know. I don’t know why standards folks hate usability so much, but the dids can be totally opaque. We’ll probably want to add something about using human-readable versions of the dids, because exposing “did:mailto:alice%40gmail.com” would be grounds for abandoning the whole did semantics and just using “alice@gmail.com” as the name (and, in fact, I think that should be the key that’s searched for). :sweat_smile:

1 Like

Just read the linked w3c issue, and it’s interesting that [roman] alphanumerics aren’t considered susceptible to semantic drift, but other characters (including international chars) are. For dids to be totally opaque, they’d probably be better off fully B64 encoded or something like that. Anyhow, NNS is explicitly about the human-level semantic meaning of the names, so yeah, I’m not super concerned about the actual did encoding, happy to go with whatever the standard says. :blush:

This is a great question – I’m actually not sure what the right semantics are going to be. I have a bunch of questions around what invalidates a UCAN; my hunch is that the semantics will actually be encoded in the UCAN itself, e.g., by including “by some mechanism” (e.g. merkle root, list, etc) the UCANs that the current one is intended to supersede. Maybe this or something like it is already part of the UCAN spec?

The TL;DR is that if your DID is anywhere in the proof chain, you can invalidate a “downstream” UCAN.

Here’s the section on revocation in the spec:

This diagram (from 6.6.1) is usually the easiest way to grok the mechanism:

               Root
        ┌────────────────┐          ─┐
        │                │           │
        │  iss: Alice    │           │
        │  aud: Bob      │           ├─ Alice can revoke
        │                │           │
        └───┬────────┬───┘           │
            │        │               │
            │        │               │
            ▼        ▼               │
┌──────────────┐  ┌──────────────┐   │  ─┐
│              │  │              │   │   │
│  iss: Bob    │  │  iss: Bob    │   │   │
│  aud: Carol  │  │  aud: Dan    │   │   ├─ Bob can revoke
│  att: [X,Y]  │  │  att: [Y,Z]  │   │   │
│              │  │              │   │   │
└───────┬──────┘  └──┬───────────┘   │   │
        │            │               │   │
        │            │               │   │
        ▼            │               │   │
┌──────────────┐     │               │   │  ─┐
│              │     │               │   │   │
│  iss: Carol  │     │               │   │   │
│  aud: Dan    │     │               │   │   ├─ Carol can revoke
│  att: [X,Y]  │     │               │   │   │
│              │     │               │   │   │
└───────────┬──┘     │               │   │   │
            │        │               │   │   │
            │        │               │   │   │
            ▼        ▼               │   │   │
        ┌────────────────┐           │   │   │  ─┐
        │                │           │   │   │   │
        │  iss: Dan      │           │   │   │   │
        │  aud: Erin     │           │   │   │   ├─ Dan can revoke
        │  att: [X,Y,Z]  │           │   │   │   │
        │                │           │   │   │   │
        └────────────────┘          ─┘  ─┘  ─┘  ─┘

I don’t know why standards folks hate usability so much

Next you’re going to ask for testable requirements, readable specs, or even sensible requirements. And where would that leave us?

More seriously, it’s a nitpick but is it worth wrapping an existing scheme in did: at all? Are you going to end up with did:tel:, did:acct:, did:dns:, did:facetime:, did:jabber:…? Since this is opaque, couldn’t it simply use existing schemes when they already name something?

1 Like

That would make life too easy :stuck_out_tongue:

Great question! It’s not just the schemes by themselves. A DID includes some verification criteria. For example, did:dns exists, and requires you to write a data into a _did. subdomain. I’m not sure how you would do verification for a did:tel other than maybe a VC from the phone company, or actually calling them “in lieu of signature”.

Irakli has been working on did:mailto at DAG House. You need to actually verify control over the email via DKIM/DMARC, or have a trusted attester (which I think is where they landed).

Perhaps what @darobin is saying is much like how we write fission.codes instead of “https://www.fission.codes” (dropping the https://www.) we will probably drop the “did:tel” part and just try looking up the phone number and seeing if it resolves or not.

Speaking of which, an alternative protocol to getting a Verifiable Credential from the TelCo would be to peer-to-peer issued Credentials across our phone books, in a web-of-trust sort of way, then simply resolve against name + number to get DID Documents.

For example (so I include a testable spec… :wink:) I could try to resolve:

// hash of cbor/borsh perhaps?
- FirstName = Brooklyn
- Tel = +1 (250) 555-1234

on a Key-Value NNS network and examine the results. Say a result includes a VCs issued by Friend of a Friend:

  • @darobin issued VC for DID Doc: 10100011011 on Aug 8, 2023
  • @bmann issued VC for DID Doc: 10100011011 on Jul 2, 2023

Since I know and trust darobin to only issue legit VCs, I know that the VC is legit and I can trust it to use the public keys therein to send a message on Nostr (or wherever).

That way we

  • don’t need a centralized issuer (TelCo)
  • phone number can go to another person and I can still find Brooklyn using her old phone number since the VC is tied to her name
  • Brooklyn can re-post updates to the network so I always can find the latest DID Doc
  • I could resolve the same DID Doc using Brooklyn’s email, home address, whatever so if I don’t have her phone number I’ll use an alternate (assuming she got them issued and posted them)

:thinking::thought_balloon: If you would use something like this, please let it be known :rocket:

Absolutely, I think NNS should leave space for web of trust methods. It’s a different verification method, and supporting both inside their namespaces (i.e. they’re not identical claims) seems sensible.

Sure; that’s possible to resolve, but not to verify. You could concievably have any number of poeple claiming to be +1 (250) 555-1234 with many different ways to verify it. What’s the verification method that I trust? Since all of this lives in a global namespace, someone can fakes having my number and give a weak or bad verificiation method. How do I communicate that you have to check my number this specific way instead of the broken method?

I agree that (many) end users won’t care about the DID method, in the sense that applications will need to run the verification for them, and thus will have a subset of methods that they support any they’ll try those (like how phone country and area codes are often implicit — i.e. a UI-layer thing, not the protocol). Others will care about the namespacing quite explicietly, in the same way that emails are relative to a domain name — it wasn’t not particaularly human friendly or common prior to email taking over the world, and folks just adapted because it was a requirement and connoted authority ("this really boris at Fission, not some other one, and sent from the fission.codes server).

not a silver bullet, but relevant trivia
https://datatracker.ietf.org/wg/enum/charter/

Flip the phone number around, put dots between each character, prepend to e164.arpa and do a DNS query.

$ORIGIN 4.3.2.1.6.7.9.8.6.4.e164.arpa.
  IN NAPTR  10 10 "u" "sip+E2U"     "!^.*$!sip:paf@swip.net!"    .
  IN NAPTR 102 10 "u" "mailto+E2U"  "!^.*$!mailto:paf@swip.net!" .
  IN NAPTR 102 10 "u" "tel+E2U"     "!^.*$!tel:+4689761234!"  

via this example

It doesn’t work for my cell phone number, but it does for some outside the US :upside_down_face:

2 Likes