Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d5673ca
Add INTEGRATION document
markg85 May 12, 2022
9630240
Update INTEGRATION.md
markg85 Nov 21, 2022
b23caf5
Merge branch 'ipfs:main' into master
markg85 Nov 21, 2022
f956141
rewrote integration document
markg85 Nov 26, 2022
8a65c2c
Remove drawio files, we're using mermaid now
markg85 Nov 26, 2022
0e8fa0d
follow the template
markg85 Nov 26, 2022
81adfd0
linter fixes
markg85 Nov 26, 2022
ed0fe22
a few more linter fixes
markg85 Nov 26, 2022
0d6b8d6
wip image instead
markg85 Nov 28, 2022
0dd13f2
review feedback and updated to new concepts
markg85 Nov 29, 2022
d362c62
Refer to the new file as gateways (plural).
markg85 Nov 29, 2022
7ce0432
Move integrations document to:
markg85 Dec 8, 2022
9e5cd95
template fixes
markg85 Dec 8, 2022
4d80040
280. Not 180.
markg85 Dec 8, 2022
50b70cf
Add global configuration details
markg85 Dec 11, 2022
c6699f7
Little less bold
markg85 Dec 11, 2022
32b1cfd
Reword the compatibility section and fix some review feedback.
markg85 Sep 25, 2023
3990b3d
Merge branch 'main' into master
markg85 Sep 25, 2023
72cdde2
Merge origin/main into markg85-master
lidel Oct 3, 2023
6ee4e19
ipip-280: update and split into specs and ipip
lidel Oct 3, 2023
6290ead
fix: typos and clarify file encoding
lidel Dec 16, 2025
85702ce
fix: clarify single vs multiple URL handling in gateway file
lidel Dec 16, 2025
9d0024f
Merge remote-tracking branch 'origin/main' into pr-280
lidel Dec 16, 2025
e657c46
docs: document out-of-scope alternatives
lidel Dec 16, 2025
a5334ca
fix: remove stray word in curl section
lidel Dec 16, 2025
c65d0a6
fix: simplify and fix OS-specific path handling
lidel Dec 16, 2025
65e6099
chore: update metadata and relax MUST to SHOULD
lidel Dec 16, 2025
7acc773
fix: clarify gateway URL requirements
lidel Dec 16, 2025
e8581ce
fix: capitalize SHOULD for RFC 2119 consistency
lidel Dec 16, 2025
81e97eb
chore: add libp2p-gateway to integratingHttpGateways
lidel Dec 16, 2025
22779d6
chore: mark IPIP as ratified (implemented since 2022)
lidel Dec 16, 2025
b4e73a2
docs: add official ffmpeg docs reference
lidel Dec 16, 2025
42ab2ae
docs: apply grammar suggestions from review
lidel Aug 7, 2026
fe6bbf5
Merge remote-tracking branch 'origin/main'
lidel Aug 7, 2026
96a56b1
spec: match gateway detection to implementations
lidel Aug 7, 2026
e2d56da
spec: browser secure context and origin isolation
lidel Aug 7, 2026
c732c43
chore: credit reviewers in frontmatter
lidel Aug 7, 2026
faebc26
spec: retitle gateway detection documents
lidel Aug 7, 2026
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
130 changes: 130 additions & 0 deletions src/http-gateways/gateway-detection.md
Original file line number Diff line number Diff line change
@@ -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/).
2 changes: 2 additions & 0 deletions src/http-gateways/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ <h3>Web</h3>
<a href="https://en.wikipedia.org/wiki/Same-origin_policy">origin-based security model</a>.
</p>
{% include 'list.html', posts: collections.webHttpGateways %}
<h3>Integration</h3>
{% include 'list.html', posts: collections.integratingHttpGateways %}
</main>

{% include 'footer.html' %}
2 changes: 1 addition & 1 deletion src/http-gateways/libp2p-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ xref:
- http-routing-v1
- path-gateway
- trustless-gateway
tags: ['httpGateways', 'lowLevelHttpGateways', 'exchange', 'transport']
tags: ['httpGateways', 'integratingHttpGateways', 'exchange', 'transport']
order: 3
---

Expand Down
4 changes: 4 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ <h3><a href="/http-gateways/">HTTP Gateways</a></h3>
Web semantics (for website hosting and web browsers):
</p>
{% include 'list.html', posts: collections.webHttpGateways %}
<p>
Other integrations:
</p>
{% include 'list.html', posts: collections.integratingHttpGateways %}
</section>
<section>
<h3><a href="/data-formats">Data Formats</a></h3>
Expand Down
154 changes: 154 additions & 0 deletions src/ipips/ipip-0280.md
Original file line number Diff line number Diff line change
@@ -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. <https://blog.ipfs.tech/2023-05-multigateway-chromium-client/>

#### 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. <https://ffmpeg.org/ffmpeg-protocols.html#ipfs>, <https://blog.ipfs.tech/2022-08-01-ipfs-and-ffmpeg/>

#### 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. <https://curl.se/docs/ipfs.html>

#### 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/).
Loading