Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPIP-351: IPNS Signed Records Response Format on HTTP Gateways #351

Merged
merged 5 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/http-gateways/path-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: >
The most versatile form of IPFS Gateway is a Path Gateway. It exposes namespaces, such
as /ipfs/ and /ipns/ under an HTTP server root and provides basic primitives for integrating
IPFS resources within the existing HTTP stack.
date: 2023-02-27
date: 2023-03-30
maturity: reliable
editors:
- name: Marcin Rataj
Expand Down Expand Up @@ -138,6 +138,7 @@ For example:
- [application/vnd.ipld.dag-cbor](https://www.iana.org/assignments/media-types/application/vnd.ipld.dag-cbor) – requests [IPLD Data Model](https://ipld.io/docs/data-model/) representation serialized into [DAG-CBOR format](https://ipld.io/docs/codecs/known/dag-cbor/). If the requested CID already has `dag-cbor` (0x71) codec, data is validated as DAG-CBOR before being returned as-is. Invalid DAG-CBON produces HTTP Error 500.
- [application/json](https://www.iana.org/assignments/media-types/application/json) – same as `application/vnd.ipld.dag-json`, unless the CID's codec already is `json` (0x0200). Then, the raw JSON block can be returned as-is without any conversion.
- [application/cbor](https://www.iana.org/assignments/media-types/application/cbor) – same as `application/vnd.ipld.dag-cbor`, unless the CID's codec already is `cbor` (0x51). Then, the raw CBOR block can be returned as-is without any conversion.
- [application/vnd.ipfs.ipns-record](https://www.iana.org/assignments/media-types/application/vnd.ipfs.ipns-record) – requests a verifiable [IPNS Record](../ipns/IPNS.md#ipns-record) to be returned. Produces 400 Bad Request if the content is not under the IPNS namespace, or contains a path.

### `Range` (request header)

Expand Down Expand Up @@ -202,14 +203,16 @@ parameter, if present)

Optional, `format=<format>` can be used to request specific response format.

This is a URL-friendly alternative to sending an [`Accept`](#accept-request-header) header. These are the equivalents:
This is a URL-friendly alternative to sending an [`Accept`](#accept-request-header) header.
These are the equivalents:
- `format=raw` → `Accept: application/vnd.ipld.raw`
- `format=car` → `Accept: application/vnd.ipld.car`
- `format=tar` → `Accept: application/x-tar`
- `format=dag-json` → `Accept: application/vnd.ipld.dag-json`
- `format=dag-cbor` → `Accept: application/vnd.ipld.dag-cbor`
- `format=json` → `Accept: application/json`
- `format=cbor` → `Accept: application/cbor`
- `format=ipns-record` → `Accept: application/vnd.ipfs.ipns-record`

<!-- TODO Planned: https://github.com/ipfs/go-ipfs/issues/8769
- `selector=<cid>` can be used for passing a CID with [IPLD selector](https://ipld.io/specs/selectors)
Expand Down Expand Up @@ -575,7 +578,9 @@ The following response types require an explicit opt-in, can only be requested w
- CAR (`?format=car`)
- Arbitrary DAG as a verifiable CAR file or a stream, see [application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car).
- TAR (`?format=tar`)
- Deserialized UnixFS files and directories as a TAR file or a stream, see [IPIP-288](https://github.com/ipfs/specs/pull/288)
- Deserialized UnixFS files and directories as a TAR file or a stream, see :cite[ipip-0288].
- IPNS Record
- Protobuf bytes representing a verifiable :cite[ipns-record] (multicodec `0x0300`)

# Appendix: notes for implementers

Expand Down
14 changes: 13 additions & 1 deletion src/http-gateways/trustless-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ description: >
Trustless Gateways are a minimal subset of Path Gateways that allow light IPFS
clients to retrieve data behind a CID and verify its integrity without delegating any
trust to the gateway itself.
date: 2022-11-09
date: 2023-03-30
maturity: reliable
editors:
- name: Marcin Rataj
github: lidel
url: https://lidel.org/
- name: Henrique Dias
github: hacdias
url: https://hacdias.com/
tags: ['httpGateways', 'lowLevelHttpGateways']
order: 1
---
Expand All @@ -36,6 +39,14 @@ Downloads data at specified CID.

Same as GET, but does not return any payload.

## `GET /ipns/{key}[?{params}]`

Downloads data at specified IPNS Key. Verifiable :cite[ipns-record] can be requested via `?format=ipns-record`

## `HEAD /ipns/{key}[?{params}]`

same as GET, but does not return any payload.

# HTTP Request

Same as in :cite[path-gateway], but with limited number of supported response types.
Expand All @@ -53,6 +64,7 @@ Below response types MUST to be supported:

- [application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw) – requests a single, verifiable raw block to be returned
- [application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car) – disables IPLD/IPFS deserialization, requests a verifiable CAR stream to be returned
- [application/vnd.ipfs.ipns-record](https://www.iana.org/assignments/media-types/application/vnd.ipfs.ipns-record) – requests a verifiable :cite[ipns-record] (multicodec `0x0300`).

# HTTP Response

Expand Down
100 changes: 100 additions & 0 deletions src/ipips/ipip-0351.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: "IPIP-0351: IPNS Signed Records Response Format on HTTP Gateways"
date: 2022-11-29
ipip: ratified
editors:
- name: Henrique Dias
github: hacdias
url: https://hacdias.com/
- name: Marcin Rataj
github: lidel
url: https://lidel.org/
relatedIssues:
- https://github.com/ipfs/specs/issues/320
- https://github.com/ipfs/specs/pull/351
- https://github.com/ipfs/kubo/pull/9399
order: 351
tags: ['ipips']
---

## Summary

Add IPNS Signed Records response format to the [HTTP Gateway](/http-gateways/).

## Motivation

Currently, the gateway allows for trustless retrieval of data under the `/ipfs`
namespace, but fetching the data as a CAR, or Block, and then verifying it locally.
This is especially important for light IPFS clients, so that they can retrieve
data from other gateways without delegating any of the trust to them. Unfortunately,
this is not possible under the `/ipns` namespace.

In contrary to DNSLink, IPNS provides cryptographically-verifiable records that
can be verified by the client. This means that, if a gateway is able to provide
the IPNS signed record to an HTTP client, trustless retrieval would also be available
under the `/ipns` namespace.

In this IPIP, we propose adding :cite[ipns-record] as a response
format to the gateway under the `/ipns` namespace, allowing for trustless
retrieval of IPNS records over HTTP as [application/vnd.ipfs.ipns-record](https://www.iana.org/assignments/media-types/application/vnd.ipfs.ipns-record) content type (multicodec `0x0300`).

## Detailed design

- :cite[trustless-gateway] can now provide a signed IPNS record upon request for `/ipns/{ipns-name}` path.
- To request the IPNS record, use one of the following methods:
- Include the `Accept: application/vnd.ipfs.ipns-record` HTTP header in the request.
- Include the `format=ipns-record` query parameter in the request URL.
- The HTTP response containing the verifiable IPNS record will have the following format:
- Header: `Content-Type: application/vnd.ipfs.ipns-record`
- Body: :cite[ipns-record] serialized as the `IpnsEntry` protobuf.

## Test fixtures

This IPIP got ratified before
[gateway-conformance](https://github.com/ipfs/gateway-conformance) existed.


The [reference implementation in Kubo 0.19](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.19.md#signed-ipns-record-response-format)
provides reusable [assertions](https://github.com/ipfs/kubo/blob/v0.19.2/test/sharness/t0124-gateway-ipns-record.sh).

:::issue
Until vendor-agnostic fixtures are added to the conformance test suite ([tracking issue](https://github.com/ipfs/gateway-conformance/issues/3)),
IPNS records for testing can be generated in Kubo by creating an IPNS record:

```bash
$ ipfs key gen <key-name>
k51Key

$ ipfs name publish /ipfs/bafyHash --key=<key-name> --ttl=<record-ttl>
Published to k51Key: /ipfs/bafyHash

$ ipfs routing get /ipns/k51Key > key.pb
```
:::

## Design rationale

The current gateway already supports different response formats via the
`Accept` HTTP header and the `format` URL query. This IPIP proposes adding
one more supported format to that list.

### User benefit

By providing IPNS records through the gateway, IPFS light clients are able
to race multiple gateways in search for an IPNS record for a certain IPNS key.
This way, IPFS light clients do not necessarily need to implement the required
machinery to fetch IPNS records from other IPFS nodes through the DHT or PubSub.

In addition, the retrieval of IPNS records is trustless in the sense that they can
be verified by the client since the IPNS record includes a cryptographic signature
provided by its creator.

### Compatibility

This IPIP proposes a new format to be added to the gateway, but does not change
any prior format. Therefore, this IPIP is backwards compatible. Please note
that IPNS records are also added to the :cite[trustless-gateway] specification.

### Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).