Skip to content

Commit 468b3ff

Browse files
committed
Propose Naam as naming system powered by IPNI
Define specification for Naming As Advertisement (Naam) protocol, which enables publication, update and resolution of IPNS records over IPNI advertisements.
1 parent 69a5f6b commit 468b3ff

File tree

1 file changed

+278
-0
lines changed

1 file changed

+278
-0
lines changed

NAAM.md

+278
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
# Naam: Naming As Advertisement
2+
3+
![wip](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square)
4+
5+
**Author(s)**:
6+
7+
- [Masih Derkani](https://github.com/masih)
8+
9+
**Maintainer(s)**:
10+
11+
- [Masih Derkani](https://github.com/masih)
12+
13+
* * *
14+
15+
**Abstract**
16+
17+
This document defines the **N**aming **A**s **A**dvertise**m**ent (Naam) protocol: a mechanism by
18+
which [IPNI](IPNI.md) can be used to both publish, and
19+
resolve [IPNS](https://github.com/ipfs/specs/blob/main/ipns/IPNS.md) records. Naam utilises the
20+
extensible IPNI [advertisement metadata](IPNI.md#metadata) to encode IPNS records and form an
21+
advertisement. The resulting advertisements are consumable by indexer nodes, just like any other
22+
advertisement. Further, to resolve IPNI records, Naam utilises the existing
23+
IPNI [multihash lookup API](IPNI.md#get-multihashmultihash) to discover IPNI records.
24+
25+
## Table of Contents
26+
27+
* [Introduction](#introduction)
28+
* [Specification](#specification)
29+
+ [IPNS Record Publication](#ipns-record-publication)
30+
+ [Updating IPNS Records](#updating-ipns-records)
31+
+ [Removing IPNS Records](#removing-ipns-records)
32+
+ [Resolving IPNS Records](#resolving-ipns-records)
33+
* [Limitations](#limitations)
34+
+ [IPNS Record Size](#ipns-record-size)
35+
+ [Record Validity Duration](#record-validity-duration)
36+
* [Security](#security)
37+
+ [Advertisement Verifiability](#advertisement-verifiability)
38+
+ [Reputation](#reputation)
39+
* [Privacy](#privacy)
40+
* [Implementations](#implementations)
41+
* [Related Resources](#related-resources)
42+
* [Copyright](#copyright)
43+
44+
## Introduction
45+
46+
IPNI introduces a set of protocols to discover providers for content-addressable data, along with
47+
the protocols over which the data can be retrieved. Content providers maintain a chain of
48+
advertisements that collectively capture the list of multihashes they provide. IPNI network is
49+
actively being integrated across multiple networks, including IPFS and FileCoin.
50+
51+
As the IPFS network grows, it is desirable to enable alternative content routing mechanisms in order
52+
to provide the best user experience possible; e.g. fast time-to-first-byte, low latency lookups,
53+
etc. IPNI already offers a DHT alternative to discover providers for a given CID. However, DHT in
54+
IPFS provides other functionalities that go beyond provider lookup. One such functionality is IPNS:
55+
InterPlanetary Naming System.
56+
57+
IPNS compliments the immutability of IPFS by providing a way to create cryptographically
58+
verifiable, mutable pointers to content-addressed data. It is part of the core IPFS functionality,
59+
which offers an intuitive way to enable naming service, such as mapping domain names to changing
60+
CIDs. For IPNI to become a complete content routing system and a viable alternative to the existing
61+
IPFS DHT it needs to support IPNS. This is where **N**aming **A**s **A**dvertise**m**ent
62+
(Naam) comes in.
63+
64+
## Specification
65+
66+
Naam is a naming protocol that build on top of the existing IPNI protocol to facilitate a naming
67+
system. It enables publication and resolution of IPNS records using the IPNI advertisements and
68+
indexer node find APIs. Naam utilises the extensible advertisement metadata field to embed IPNS
69+
records and produce advertisements that are consumable by existing indexer nodes without requiring
70+
any change to the existing ingestion pipeline nor lookup API.
71+
72+
This approach offers two key advantages; it:
73+
74+
1) reuses the existing IPNI network to implement a name service, which takes IPNI closer to offering
75+
a fully featured DHT alternative for the IPFS network without having to run any additional
76+
services dedicated to resolving IPNS records , and
77+
2) preserves an immutable historical catalogue of all IPNS records published by a peer, which can be
78+
used for reputation analysis and ultimately holding peers responsible for their participation in
79+
the network.
80+
81+
Naam naming system involves three main components:
82+
83+
1) **Publisher** - which makes a chain of specifically crafted advertisements available for
84+
ingestion by the network indexers,
85+
2) **Network Indexer** - which is an IPNI node responsible for ingesting advertisements and exposing
86+
find APIs, and
87+
3) **Resolver** - which with the aid of network indexers given an IPNS key resolves its
88+
corresponding record.
89+
90+
The flow of information between the three components is similar to the indexing ecosystem depicted
91+
in IPNI spec: publishers create and publish advertisements -> network indexers ingest them -> and
92+
similar to retrieval clients resolvers use the find API to map a given IPNS key to IPNS record. In
93+
this flow no changes are needed on network indexers. Therefore, the reminder of this document
94+
focuses on interactions of Publishers, Resolvers and the data format exchanged between them. For
95+
more information on how network indexers ingest advertisements and provide lookup APIs, please
96+
see [IPNI](IPNI.md).
97+
98+
### IPNS Record Publication
99+
100+
Naam publishes IPNS records via Publishers, which create IPNI-compliant advertisements that
101+
embed IPNS records and are signed by their identity. The produced advertisements consist of:
102+
103+
* **`PreviousID`** - the optional link to the previous Naam advertisement. `nil` indicates no
104+
previous advertisements.
105+
* **`Provider`** - the publisher peer ID.
106+
* **`Addresses`** - the array of multiaddrs over which the publisher can be reached.
107+
* **`Entries`** - the link to an `EntryChunk` IPLD node, as specified by IPNI, that contains a
108+
single entry: the multihash of IPNS record key with `nil` as link to `Next`.
109+
* **`ContextID`** - fixed to UTF-8 bytes encoding of the value `/ipni/naam`.
110+
* **`Metadata`** - the bytes representation of Naam metadata, consisting of:
111+
* the varint representation of IPNS multicodec code, i.e. `0xe5`, as bytes,
112+
* followed by the marshalled IPNS record.
113+
* **`IsRm`** - the boolean value specifying weather an IPNS entry is being added/updated,
114+
i.e. `true`, or removed, i.e. `false`.
115+
* **`Signature`** - the advertisement signature calculated as specified by IPNI specification.
116+
117+
#### `Entries`
118+
119+
`Entires` in a typical advertisement are responsible for capturing the list of multihashes
120+
corresponding to the content hosted by a provider. Once ingested, the indexer nodes facilitate
121+
lookup of providers over find APIs via the same multihashes.
122+
123+
Naam repurposes the same advertisement structure by specifically crafting entries of advertisement
124+
such that the indexer node find API can also be repurposed to lookup IPNS records. Naam forms a
125+
single `EntryChunk` IPLD node, that contains a single multihash calculated as:
126+
127+
* the SHA-256 of IPNS Record Key, i.e. `/ipns/<peer-ID>`.
128+
129+
This approach allows the resolvers to deterministically calculate the multihash used for lookup when
130+
interacting with the indexer node find APIs.
131+
132+
#### Context ID
133+
134+
The field `ContextID` in a regular advertisement is used as a way to uniquely identify the metadata
135+
associated to a list of multihashes. Naam uses a fixed value, `/ipni/naam`, as context ID to assure
136+
that the metadata associated to the published advertisement for the same IPNI key is singular and
137+
uniquely identifiable.
138+
139+
Using a fixed value as context ID also enables network indexers to quickly differentiate Naam
140+
advertisements from a typical content advertisement. This opens up future opportunities for
141+
optimisation when it comes to ingesting Naam advertisements. For example, indexers can pro-actively
142+
process IPNS records and offer bespoke APIs that understand IPNS record expiry/validity.
143+
144+
#### Metadata
145+
146+
`Metadata` is typically used to convey the list of protocols over which the advertised content is
147+
retrievable. Further, this field is designed to be extensible: a valid metadata should start with a
148+
`varint` signifying _some_ protocol ID followed by arbitrary bytes. There are currently three well
149+
known protocol IDs. The protocol ID itself need not to be known by the indexer nodes. In fact,
150+
indexers treat metadata as a black box and carry on processing advertisements. Instead, it is meant
151+
to be a signal to the consumers of `Metadata`, i.e. retrieval clients, as a hint on how to decode
152+
the remaining bytes.
153+
154+
Naam utilises this extensibility to directly encode IPNS records as metadata. The Naam advertisement
155+
metadata consists of:
156+
157+
* `ipns` multicodec code `0xe5` as protocol ID,
158+
* followed by marshalled IPNS Record.
159+
160+
The use of metadata to capture IPNS records enables Naam to also utilise the built-in IPNI mechanism
161+
for updating metadata to update IPNS records. Because, context ID nor the multihash in Naam
162+
advertisements ever change for the same IPNS key. For more information,
163+
see [Updating IPNS Records](#updating-ipns-records).
164+
165+
Note that the IPNS multicodec code `0xe5` is tagged as "namespace" in the CSV table, which could
166+
signify an IPNS path, not record. There is currently no multicodec code for IPNS records themselves.
167+
Alternatively, a new multicodec code can be introduced to the
168+
[multicodec CSV file](https://github.com/multiformats/multicodec/blob/master/table.csv) to avoid
169+
potential confusion between the two. The new code can then be used as the Protocol ID of Naam
170+
Metadata.
171+
172+
### Updating IPNS Records
173+
174+
IPNI offers a built-in mechanism to efficiently update the metadata associated to a list of
175+
multihashes without having to republish the entries. Indexer nodes uniquely identify the metadata by
176+
the advertisement `Provider`, and `ContextID`.
177+
178+
Both of these values remain the same in Naam advertisements: the former is the same peer ID that
179+
forms part of the IPNS key, i.e. `/ipns/<peer-id>`, and the latter is fixed. As a result, to update
180+
an IPNS record, all that's needed is to publish a new Naam advertisement that:
181+
182+
* links to the previous advertisement in `PrevousID` link as specified by IPNI,
183+
* uses the same `Provider` and `ContextID` values as before,
184+
* sets `IsRm` to `false`, and
185+
* has the updated IPNS record in Naam Metadata format.
186+
187+
Note that there is no need to specify `Entries` when updating an existing record. It is inferred by
188+
the network indexers since `Provider` and `ContextID` in Naam advertisements never change.
189+
190+
### Removing IPNS Records
191+
192+
IPNS has EOL and TTL features built-in. This means explicit removal of records is not strictly
193+
required. Instead, records eventually expire. Though not strictly necessary, Naam protocol can
194+
utilise IPNI to explicitly remove records just like a traditional DNS nameserver.
195+
196+
The process to remove an IPNS record published via Naam protocol is identical to removal
197+
advertisement specified by IPNI. Similar to a regular advertisement, an IPNS record may be removed
198+
by publishing an advertisement that:
199+
200+
* links to the previous advertisement in `PrevousID` link as specified by IPNI,
201+
* uses the same `Provider` and `ContextID` values as before,
202+
* sets `IsRm` to `true`, and
203+
* sets `Entries` link to `NoEntries` as specified by IPNI.
204+
205+
Once ingested, indexer nodes will eventually remove the Naam advertisement metadata along with the
206+
publisher information.
207+
208+
### Resolving IPNS Records
209+
210+
IPNS record resolution involves finding the IPNS record associated to a given IPNS key, i.e.
211+
`/ipns/<peer-id>`. As eluded to earlier, Naam uses the find API already provided by the network
212+
indexers to achieve this. To resolve an IPNS record, a resolver:
213+
214+
* calculates the multihash of the given IPNS key as its SHA-256,
215+
* looks up the provider info for that multihash via the IPNI find API,
216+
* decodes the metadata from the provider info as IPNS record,
217+
* validates the record, and
218+
* if valid returns its value.
219+
220+
## Limitations
221+
222+
### IPNS Record Size
223+
224+
The maximum size of IPNS records supported by Naam is 1 KiB, even though IPNS specification suggests
225+
a maximum limit of 10 KiB. The 1 KiB limit currently imposed by network indexers on the maximum size
226+
of advertisement metadata.
227+
228+
Basic tests show that a 1KiB limit is sufficiently large for storing simple IPNS records pointing to
229+
IPFS paths, specially for records that do not need the peer's public key to be embedded into IPNS
230+
records. For example, a Ed25519 peer ID also captures the peer's public key. A marshalled IPNS
231+
record with such key type and empty value constructed
232+
using [`go-ipns`](https://github.com/ipfs/go-ipns) library comes to `257` bytes, which leaves
233+
sufficient space for encoding fairly long IPFS paths as the record value.
234+
235+
### Record Validity Duration
236+
237+
The indexers will maintain information from inactive providers for up to a week. This means IPNS
238+
records published by Naam with EOL of beyond a week should be re-published to remain resolvable.
239+
240+
## Security
241+
242+
### Advertisement Verifiability
243+
244+
Naam advertisements will benefit from all the verifiability features of regular advertisements. They
245+
are signed by the IPNS record publisher and are verified for validity before being ingested by the
246+
network indexers.
247+
248+
### Reputation
249+
250+
Similar to the IPNI indexing protocol, the use of immutable advertisement chain by Naam provides a
251+
verifiable and immutable catalog of IPNS records exposed by a network participant. Access to such
252+
historical data enables verifiable analysis of participant behaviour, and offers an opportunity to
253+
design and develop reputation systems, which ultimately can contribute to the health of the network.
254+
As far as I know, this is something that is not currently offered by the existing implementations of
255+
IPNS.
256+
257+
Even though, the specification of such reputation system is beyond the scope of this document, it is
258+
important to point out such potential. Because, as the size of IPFS network grows so will the need
259+
for reputation systems that enable users to choose from ever increasing "choices" across the
260+
network.
261+
262+
## Privacy
263+
264+
To be revisited when double-hashing work is finalised.
265+
266+
## Implementations
267+
268+
* [`ipni/go-naam`](https://github.com/ipni/go-naam) - Golang implementtion of IPNI Naam protocol.
269+
270+
## Related Resources
271+
272+
* [IPNS: InterPlanetary Naming System](https://github.com/ipfs/specs/blob/main/ipns/IPNS.md)
273+
* [IPNS PubSub Router](https://github.com/ipfs/specs/blob/main/ipns/IPNS_PUBSUB.md)
274+
* [IPNI: InterPlanetary Network Indexer](https://IPNI.md)
275+
276+
## Copyright
277+
278+
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

0 commit comments

Comments
 (0)