|
| 1 | +# IPFS Addressing in Web Browsers |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +> ### Status of This Memo |
| 6 | +> |
| 7 | +> This living document specifies current set of conventions for the IPFS community, |
| 8 | +> and requests discussion and suggestions for improvements via PR. |
| 9 | +
|
| 10 | +## Table of Contents |
| 11 | + |
| 12 | +- [Summary](#tldr) |
| 13 | +- [References](#references) |
| 14 | +- [Appendices](#appendices) |
| 15 | + - Notes on addressing with [http://](#notes-on-addressing-with-http) |
| 16 | + - Notes on addressing with [ipfs://](#notes-on-addressing-with-ipfs) |
| 17 | + |
| 18 | +## TL;DR |
| 19 | + |
| 20 | +### Addressing with HTTP |
| 21 | + |
| 22 | + |
| 23 | +When site isolation does not matter gateway can expose IPFS namespaces as regular URL paths: |
| 24 | + |
| 25 | + https://<gateway-host>.tld/ipfs/<cid>/path/to/resource |
| 26 | + https://<gateway-host>.tld/ipns/<cid>/path/to/resource |
| 27 | + |
| 28 | +When origin-based security perimeter is needed, [CIDv1](https://github.com/ipld/cid#cidv1) in Base32 ([RFC4648](https://tools.ietf.org/html/rfc4648#section-6), no padding) should be used in subdomain: |
| 29 | + |
| 30 | + https://<cidv1-base32>.ipfs.<gateway-host>.tld/path/to/resource |
| 31 | + https://<peerid-base32>.ipns.<gateway-host>.tld/path/to/resource |
| 32 | + |
| 33 | + |
| 34 | +For more context see [notes on addressing with HTTP](#notes-on-addressing-with-http) below. |
| 35 | + |
| 36 | +### Addressing with Native URL |
| 37 | + |
| 38 | +In future, subdomain convention will be replaced with native handler that provides the same origin-based guarantees: |
| 39 | + |
| 40 | + ipfs://{cidv1b32}/path/to/resource |
| 41 | + |
| 42 | +## References |
| 43 | +- [The four stages of the upgrade path for path addressing](https://github.com/ipfs/specs/pull/152#issuecomment-284628862) |
| 44 | +- [CID as a Subdomain](https://github.com/ipfs/in-web-browsers/issues/89) |
| 45 | +- [IPFS: Migration to CIDv1 (default base32)](https://github.com/ipfs/ipfs/issues/337) |
| 46 | +- [Support Custom Protocols in WebExtension](https://github.com/lidel/ipfs-firefox-addon/issues/164) |
| 47 | +- [mozilla/libdweb experiment: ipfs:// protocol handler](https://github.com/ipfs-shipyard/ipfs-companion/pull/533) |
| 48 | + |
| 49 | +## Appendices |
| 50 | + |
| 51 | +### Notes on addressing with `http://` |
| 52 | + |
| 53 | +The first stage on the upgrade path are HTTP gateways. |
| 54 | + |
| 55 | +Gateways are provided strictly for convenience to help tools that speak HTTP |
| 56 | +but do not speak distributed protocols such as IPFS. This approach has been |
| 57 | +working well since 2015 but comes with a significant set of limitations related |
| 58 | +to the centralized nature of HTTP and some of its semantics. Location-based |
| 59 | +addressing of a gateway depends on both DNS and HTTPS/TLS, which relies on the trust in |
| 60 | +Certificate Authorities and PKI. In the long term these issues SHOULD be |
| 61 | +mitigated by use of opportunistic protocol upgrade schemes. |
| 62 | + |
| 63 | +#### Opportunistic Protocol Upgrade |
| 64 | + |
| 65 | +Tools and [browser extensions](https://github.com/ipfs-shipyard/ipfs-companion) SHOULD detect valid IPFS paths and resolve them |
| 66 | +directly over IPFS protocol and use HTTP gateway ONLY as a fallback when no |
| 67 | +native implementation is available to ensure a smooth, backward-compatible |
| 68 | +transition. |
| 69 | + |
| 70 | + |
| 71 | +#### Gateway Semantics |
| 72 | + |
| 73 | + |
| 74 | +In the most basic scheme an URL path used for content addressing is effectively a |
| 75 | +resource name without a canonical location. HTTP Gateway provides the location |
| 76 | +part, which makes it possible for browsers to interpret content path as |
| 77 | +relative to the current server and just work without a need for any conversion. |
| 78 | + |
| 79 | +HTTP gateway SHOULD: |
| 80 | +- Take advantage of existing caching primitives, namely: |
| 81 | + - Set `Etag` HTTP header to the canonical CID of returned payload |
| 82 | + - Set `Cache-Control: public,max-age=29030400,immutable` if resource |
| 83 | + belongs to immutable namespace (eg. `/ipfs/*`) |
| 84 | +- set `Suborigin` header based on the hash of the root of current content tree |
| 85 | +- provide a meaningful directory index for root resources representing file |
| 86 | + system trees |
| 87 | + |
| 88 | +HTTP gateway MAY: |
| 89 | +- Customize style of directory index. |
| 90 | +- Return a custom payload along with error responses (HTTP 400 etc). |
| 91 | +- Provide a writable (`POST`, `PUT`) access to exposed namespaces. |
| 92 | + |
| 93 | + |
| 94 | +##### Origin Workaround #1: Subdomains |
| 95 | + |
| 96 | +Gateway operator MAY work around single Origin limitation by creating artificial |
| 97 | +subdomains based on URL-safe version of root content identifier (eg. |
| 98 | +`<cidv1b32>.ipfs.foo.tld`). Each subdomain provides separate Origin and creates an |
| 99 | +isolated security context at a cost of obfuscating path-based addressing. |
| 100 | + |
| 101 | +Benefits of this approach: |
| 102 | + |
| 103 | +- The ability to do proper security origins without introducing any changes to |
| 104 | + preeexisting HTTP stack. |
| 105 | +- Root path of content-addressed namespace becomes the root of URL path, which |
| 106 | + makes asset adressing compatible with existing web browsers: `<img |
| 107 | + src="/rootimg.jpg">` |
| 108 | +- Opens up the ability for [HTTP Host |
| 109 | + header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host) and |
| 110 | + [TLS SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) parsing, |
| 111 | + which is a prerequisite for fully automated deployment of TLS via Let's Encrypt. |
| 112 | + |
| 113 | +According to [RFC 1035](http://tools.ietf.org/html/rfc1035) subdomains (aka |
| 114 | +"labels", hostnames) are case-insensitive, which severly constraints the number |
| 115 | +of content addressing identifier types that can be used without need for an |
| 116 | +additional conversion step. |
| 117 | + |
| 118 | +Due to this IPFS community [decided](https://github.com/ipfs/ipfs/issues/337) to use lowercased base32 |
| 119 | +([RFC4648](https://tools.ietf.org/html/rfc4648#section-6) - no padding - highest letter) |
| 120 | +as the default base encoding of [CIDv1](https://github.com/ipld/cid#cidv1) (our binary identifiers). |
| 121 | + |
| 122 | + |
| 123 | +##### Origin Workaround #2: Suborigin |
| 124 | + |
| 125 | +Suborigins are a |
| 126 | +[work-in-progress](https://w3c.github.io/webappsec-suborigins/) standard to |
| 127 | +provide a new mechanism for allowing sites to separate their content by |
| 128 | +creating synthetic origins while serving content from a single physical origin. |
| 129 | + |
| 130 | +A [`suborigin` header](https://w3c.github.io/webappsec-suborigins/#the-suborigin-header) |
| 131 | +SHOULD be returned by HTTP gateway and contain a value |
| 132 | +unique to the current content addressing root. |
| 133 | + |
| 134 | +Unfortunately due to limited adoption suborigin have no practical use. |
| 135 | + |
| 136 | + |
| 137 | +### Notes on addressing with `ipfs://` |
| 138 | + |
| 139 | +The `ipfs://` protocol scheme follows the same requirement of CIDv1 in Base32 as [subdomains](#origin-workaround-1-subdomains). |
| 140 | +It does not retain original path, but instead requires a conversion step to/from URI: |
| 141 | +> `ipfs://{immutable-root}/path/to/resourceA` → `/ipfs/{immutable-root}/path/to/resourceA` |
| 142 | +> `ipns://{mutable-root}/path/to/resourceB` → `/ipns/{mutable-root}/path/to/resourceB` |
| 143 | +
|
| 144 | +The first element after double slash is an opaque identifier representing |
| 145 | +the content root. It is interpreted as an authority component used for Origin |
| 146 | +calculation, which provides necessary isolation between security contexts of diferent content trees. |
| 147 | + |
| 148 | + |
0 commit comments