diff --git a/src/http-gateways/gateway-detection.md b/src/http-gateways/gateway-detection.md new file mode 100644 index 000000000..e3cff5a3a --- /dev/null +++ b/src/http-gateways/gateway-detection.md @@ -0,0 +1,130 @@ +--- +title: User-Preferred Gateway Detection +description: > + How applications detect the user-preferred IPFS Gateway via the + IPFS_GATEWAY environment variable or a well-known gateway file. +date: 2026-08-07 +maturity: reliable +editors: + - name: Mark Gaiser + github: markg85 + - name: Marcin Rataj + github: lidel + affiliation: + name: Shipyard + url: https://ipshipyard.com +thanks: + - name: Tim Perry + github: pimterry + - name: Dietrich Ayala + github: autonome + - name: Dave Justice + github: meandavejustice + - name: dirkf + github: dirkf + - name: Daniel Norman + github: 2color +tags: ['httpGateways', 'integratingHttpGateways'] +order: 99 +--- + +## Introduction + +This document defines conventions for how applications can identify an available +IPFS Gateway, and how IPFS Gateway implementations can signal their own endpoint to +client applications. + +## Specification + +There are two ways of hinting the user-preferred gateway URL: + +- Setting the `IPFS_GATEWAY` environment variable +- Creating a `gateway` file at a well-known path + +Applications SHOULD evaluate these hints in order and stop on the first match: + +1. Check if a valid `IPFS_GATEWAY` environment variable is set +2. Check if a valid `gateway` file is present at one of the well-known filesystem paths + +If a hint is present but its value is not a valid URL, applications SHOULD +report an error instead of silently falling back to the next hint. + +If no valid hint is found, gateway selection is unconfigured. Applications +SHOULD NOT fall back to a hard-coded non-localhost gateway (see Security below). + +### `IPFS_GATEWAY` Environment Variable + +When the `IPFS_GATEWAY` environment variable is set, the value SHOULD be interpreted +as the URL of the IPFS Gateway to use. The value holds a single URL, following +the same rules as the first line of the `gateway` file. + +Applications SHOULD give this variable precedence over gateway URLs from +internal application configuration. Explicit per-invocation user input, such as +a command-line argument, MAY take precedence over this variable. + +### The `gateway` Configuration File + +Client application SHOULD check if file is present at specific filesystem paths, in order: + +1. If `IPFS_PATH` is set, try `$IPFS_PATH/gateway` +2. Otherwise, if `HOME` is set, try `$HOME/.ipfs/gateway` (the default `IPFS_PATH` location) +3. Try OS-specific paths: + - Linux/Unix: + 1. `$XDG_CONFIG_HOME/ipfs/gateway` (only if `XDG_CONFIG_HOME` is set) + 2. `$HOME/.config/ipfs/gateway` (default XDG location) + 3. `/etc/ipfs/gateway` (system-wide) + - Windows: + 1. `%LOCALAPPDATA%/ipfs/gateway` (local user) + 2. `%APPDATA%/ipfs/gateway` (roaming user) + 3. `%PROGRAMDATA%/ipfs/gateway` (system-wide) + - macOS: + 1. `$HOME/Library/Application Support/ipfs/gateway` (user) + 2. `/Library/Application Support/ipfs/gateway` (system-wide) + +When `gateway` file is present, the file contents MUST be interpreted as an +ASCII text file with one URL per line (separated by `\n` or `\r\n`). + +The first line MUST be a valid `http://` or `https://` URL consisting only of +a scheme, host, and optional port, with no path, query, or fragment +(e.g., `http://127.0.0.1:8080`). The gateway at this URL MUST support +:cite[trustless-gateway], SHOULD support :cite[path-gateway] when deserialized +responses are required, and SHOULD support :cite[subdomain-gateway] when Origin +isolation is required. + +Implementations MAY support additional lines for gateway pools or failover. +Additional lines, when present, MUST follow the same URL rules, and empty +lines MUST be ignored. Implementations that do not support multiple URLs +SHOULD read only the first line and ignore the rest of the file. + +### Security + +Applications that integrate IPFS support via HTTP gateways: + +- SHOULD NOT hard-code a non-localhost URL as a default fallback. Instead, they + SHOULD ask the user to define a preferred IPFS gateway using one of the + methods defined in this document. +- SHOULD either warn the user when a non-localhost gateway is used for + deserialized responses (risk of MITM), or (preferred) limit HTTP use + outside of localhost to verifiable response types defined in + :cite[trustless-gateway]. +- When running in a web browser, SHOULD use a gateway URL that qualifies as a + [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Secure_Contexts): + either `https://`, or localhost (e.g., `http://127.0.0.1:8080`), which + browsers treat as potentially trustworthy. +- When Origin isolation is required, SHOULD use a :cite[subdomain-gateway] + (e.g., `http://{cid}.ipfs.localhost:8080`), so each content root is loaded + from its own origin. + +### Privacy and User Control + +Applications SHOULD NOT default to public gateways (see Security above). +Instead, applications SHOULD suggest to the user how to run a local node. + +### Compatibility and Testing + +Implementers SHOULD test against implementations mentioned in :cite[ipip-0280] +as the baseline for making decisions around maximizing interoperability. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/http-gateways/index.html b/src/http-gateways/index.html index 27b633a18..650248bf8 100644 --- a/src/http-gateways/index.html +++ b/src/http-gateways/index.html @@ -19,6 +19,8 @@

Web

origin-based security model.

{% include 'list.html', posts: collections.webHttpGateways %} +

Integration

+ {% include 'list.html', posts: collections.integratingHttpGateways %} {% include 'footer.html' %} diff --git a/src/http-gateways/libp2p-gateway.md b/src/http-gateways/libp2p-gateway.md index aa6781579..9c7ee1b68 100644 --- a/src/http-gateways/libp2p-gateway.md +++ b/src/http-gateways/libp2p-gateway.md @@ -19,7 +19,7 @@ xref: - http-routing-v1 - path-gateway - trustless-gateway -tags: ['httpGateways', 'lowLevelHttpGateways', 'exchange', 'transport'] +tags: ['httpGateways', 'integratingHttpGateways', 'exchange', 'transport'] order: 3 --- diff --git a/src/index.html b/src/index.html index d5b3e1b3b..127b2c707 100644 --- a/src/index.html +++ b/src/index.html @@ -107,6 +107,10 @@

HTTP Gateways

Web semantics (for website hosting and web browsers):

{% include 'list.html', posts: collections.webHttpGateways %} +

+ Other integrations: +

+ {% include 'list.html', posts: collections.integratingHttpGateways %}

Data Formats

diff --git a/src/ipips/ipip-0280.md b/src/ipips/ipip-0280.md new file mode 100644 index 000000000..2b1de6f04 --- /dev/null +++ b/src/ipips/ipip-0280.md @@ -0,0 +1,154 @@ +--- +title: "IPIP-0280: App Conventions for Gateway Detection" +date: 2026-08-07 +ipip: ratified +editors: + - name: Mark Gaiser + github: markg85 + - name: Marcin Rataj + github: lidel + affiliation: + name: Shipyard + url: https://ipshipyard.com +relatedIssues: + - https://github.com/ipfs/kubo/issues/8847 + - https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/f889837e00d3b2388a24c0a9d075ad62f47da825 + - https://github.com/curl/curl/pull/8805 +thanks: + - name: Tim Perry + github: pimterry + - name: Dietrich Ayala + github: autonome + - name: Dave Justice + github: meandavejustice + - name: dirkf + github: dirkf + - name: Daniel Norman + github: 2color +order: 280 +tags: ['ipips'] +--- + +## Summary + +This IPIP creates conventions for how applications can identify an available IPFS gateway, +and how IPFS gateway implementations can signal their own endpoint. + +This convention has been implemented and in use since 2022 (Kubo 0.15, ffmpeg), +with curl support added in curl 8.4.0 (2023). + +## Motivation + +Applications wanting to leverage IPFS Gateways are, without a common +convention, left to invent their own ways of finding a gateway, including naive +approaches such as localhost port scanning. + +This IPIP introduces specification that defines how an application wanting to +implement IPFS support can find a local or user-preferred gateways. + +## Detailed design + +We introduce two ways of hinting user-preferred gateway URL to cover +the majority of runtimes and use cases: + +- `IPFS_GATEWAY` environment variable +- `gateway` file and filesystem paths to look for it + +See: :cite[gateway-detection] for details. + +## Design rationale + +### User benefit + +End users can define their preferred gateway once, and benefit from +opportunistic support in applications they use. + +Application developers save time as they only need to implement support for +vendor-agnostic convention to be able to read user preferred gateway. + +### Compatibility + +#### Kubo + +Kubo ([0.15.0 and later](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.15.md#-ipfs_pathgateway-file)) +creates a hint file in `$IPFS_PATH/gateway` (default being `$HOME/.ipfs/gateway`, see [kubo#8847](https://github.com/ipfs/kubo/issues/8847)). + +The file contains a single line being the local HTTP gateway URL. For example: `http://localhost:8080`. + +Every time `ipfs daemon` starts with the gateway enabled, it updates the content of `$IPFS_PATH/gateway` or creates the file if it doesn't exist. + +#### IPFS Chromium + +ipfs-chromium uses `IPFS_GATEWAY` environment variable +([ipfs-chromium#29](https://github.com/little-bear-labs/ipfs-chromium/issues/29)). + +It can be a single URL, or a whitespace-separated URLs to be used as the initial gateway pool. + +Ref. + +#### FFMPEG + +FFMPEG's libavformat tries the `-gateway` option first, then the `IPFS_GATEWAY` +environment variable, then the `gateway` file under `$IPFS_PATH` or `$HOME/.ipfs/` +([ffmpeg.git/commit/f889837](https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/f889837e00d3b2388a24c0a9d075ad62f47da825)). +Note that ffmpeg joins `$IPFS_PATH` and `gateway` without a path separator, so +file detection via `IPFS_PATH` works only when the value ends with `/`. + +The initial implementation fell back to a hard-coded public gateway; this was +removed in [ffmpeg.git/commit/412922c](https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/412922cc6fa790897ef6bb2be5d6f9a5f030754d) +for the reason the Security section of :cite[gateway-detection] codifies. + +Ref. , + +#### Curl + +Curl (8.4.0 and later, [curl#8805](https://github.com/curl/curl/pull/8805)) +will try the `IPFS_GATEWAY` environment variable first, and then look for +`$IPFS_PATH/gateway` or `$HOME/.ipfs/gateway`, if present. The `--ipfs-gateway` +flag takes precedence over both. + +It expects a single URL. Since curl 8.5.0 only the first line of the `gateway` +file is read; 8.4.0 concatenated all lines. + +Ref. + +#### ipfsspec + +Python's [ipfsspec](https://github.com/fsspec/ipfsspec) (0.5.0 and later, +[ipfsspec#29](https://github.com/fsspec/ipfsspec/issues/29)) enables `ipfs://` +support in the fsspec ecosystem. It tries the `IPFS_GATEWAY` environment +variable first (a single URL), then reads the first line of a `gateway` file, +checking `$IPFS_PATH/gateway`, `$HOME/.ipfs/gateway`, +`$XDG_CONFIG_HOME/ipfs/gateway`, `/etc/ipfs/gateway`, and OS-specific paths, +in that order ([`get_gateway` in `async_ipfs.py`](https://github.com/fsspec/ipfsspec/blob/main/ipfsspec/async_ipfs.py)). +When no gateway is found, it raises an error suggesting to run a local node +instead of falling back to a public gateway. + +### Security + +See "Security" section of :cite[gateway-detection]. + +### Alternatives + +#### Browser Environment Detection + +Detection via browser APIs (e.g., `localStorage.getItem('IPFS_GATEWAY')`) was +considered but is explicitly out of scope. Any JavaScript running on a page +could overwrite such values and hijack gateway requests. Browser-based detection +requires a separate IPIP with proper security review. + +#### Gateway Health Checking + +This specification does not mandate health checking of detected gateways. +Implementations MAY verify that a gateway is responsive before using it, +but the specific approach is left to implementers. + +#### Stale Gateway File Handling + +If a daemon crashes without removing the `gateway` file, it may contain a stale +URL. This specification does not mandate specific handling. Implementations MAY +implement timeout-based health checks or other recovery mechanisms. + +### Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).