Skip to content
Draft
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
119 changes: 119 additions & 0 deletions 26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# NUT-26: OHTTP Transport for Mint APIs

`optional`

`depends on: NUT-06`

---

This NUT specifies how a Cashu mint can offer its HTTP API over Oblivious HTTP (OHTTP) to improve network‑level privacy for wallets. OHTTP lets a client send encrypted requests to an oblivious gateway (optionally via a relay). The gateway decrypts, forwards the plaintext HTTP request to the mint, and encrypts the response, preventing the mint from learning the client's network address and preventing the relay from seeing request contents.

This NUT does not change any existing Cashu API semantics. It only defines discovery and endpoints needed to use OHTTP with a mint.

## Terminology

- OHTTP: Oblivious HTTP as specified by the IETF OHAI working group.
- Gateway: The component that holds the OHTTP key config, decapsulates requests, forwards them to the mint backend, and encapsulates responses.
- Relay: A forwarder that sees only encrypted OHTTP messages and forwards them to the gateway.
Comment thread
thesimplekid marked this conversation as resolved.

For optimal privacy, the relay and mint SHOULD be operated by different entities that do not collude. The privacy guarantees of OHTTP depend on the relay and mint not working together to correlate user traffic patterns.

## Gateway Endpoints

A gateway MUST expose the following endpoint:

- `GET /.well-known/ohttp-gateway` → returns the OHTTP key configuration
- `POST /.well-known/ohttp-gateway` → accepts encapsulated OHTTP requests
- Request content type: `message/ohttp-req`
- Response content type: `message/ohttp-res`
- Body: opaque binary as defined by OHTTP

The GET method returns the OHTTP key configuration with content type `application/ohttp-keys` as specified in [RFC 9458](https://www.rfc-editor.org/rfc/rfc9458).

## Gateway Purpose Discovery

Gateways that support Cashu over OHTTP MUST implement a purpose discovery mechanism so clients can verify Cashu support before use. Wallets MUST verify the presence of the Cashu purpose via this mechanism before using an OHTTP gateway for Cashu operations.

### Gateway Requirements

Gateways MUST:

1. Endpoint support: Respond to GET requests at `/.well-known/ohttp-gateway` when the `allowed_purposes` query parameter is present
2. Content-Type: Return `application/x-ohttp-allowed-purposes` as the Content-Type header
3. Encoding: Encode the purpose list using ALPN ProtocolNameList format (a sequence of length‑prefixed strings; each name is a 1‑byte length followed by that many UTF‑8 bytes)
4. Magic string: Include the exact Cashu purpose string: `Cashu 2253f530-151f-4800-a58e-c852a8dc8cff`

Wire format example (single purpose):

- Body bytes: `0x2a || "Cashu 2253f530-151f-4800-a58e-c852a8dc8cff"`
- `0x2a` (42 decimal) is the length of the ASCII string that follows

### Example

Request:

```http
GET /.well-known/ohttp-gateway?allowed_purposes HTTP/1.1
Host: gateway.example.com
```

Cashu-supporting gateway response:

```http
HTTP/1.1 200 OK
Content-Type: application/x-ohttp-allowed-purposes

<ALPN ProtocolNameList payload containing: "Cashu 2253f530-151f-4800-a58e-c852a8dc8cff">
```

## Client Behavior

- TLS: Wallets MUST use HTTPS and perform standard certificate validation when fetching OHTTP key configuration and when sending encapsulated requests to the gateway.
- URL resolution: If `gateway_url` is omitted in NUT‑06, wallets SHOULD assume the gateway endpoint is available on the mint’s origin at `/.well-known/ohttp-gateway`.
- Key consistency: Wallets SHOULD implement key consistency checks as described in the Privacy Pass Key Consistency draft to detect potential key attacks. See [draft-ietf-privacypass-key-consistency-01](https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01). A mechanism analogous to certificate transparency logs may be specified in future extensions for both OHTTP keys and Cashu token public keys.
- Encapsulation: Wallets construct a BHTTP request ([RFC 9292](https://www.rfc-editor.org/info/rfc9292)) that mirrors a normal Cashu API call (method, scheme, authority, path, headers, and body), encapsulate it with the fetched key config, and send it to the OHTTP gateway endpoint at `"/.well-known/ohttp-gateway"` through a relay.
- Headers: Wallets include the same application‑level headers they would send directly to the mint (e.g., auth headers if applicable). The gateway forwards headers to the mint backend.
- Paths: The BHTTP request path is the regular Cashu API path (e.g., `/v1/mint/quote/bolt11`, `/v1/melt/bolt11`, `/v1/swap`, etc.). The gateway forwards the request to the mint backend preserving method, path, headers, and body.

Wallets MUST send OHTTP messages through a relay to the gateway. Direct‑to‑gateway use defeats unlinkability between client and mint and is out of scope for this NUT.

## Errors

### Transport-Level Errors

Relays SHOULD forward HTTP responses from the gateway transparently, including error status codes. Gateways SHOULD respond with appropriate HTTP status codes for transport‑level errors (e.g., malformed OHTTP requests, key configuration issues).

### Application-Level Errors

Since request/response bodies are OHTTP‑encapsulated, application‑level Cashu errors from the mint backend remain unchanged and are handled by the wallet after decapsulation. The relay and gateway transparently forward these errors without modification.

## Security Considerations

- OHTTP provides network‑level unlinkability between client and mint. It does not hide application data from the gateway operator; the gateway must be trusted to forward requests without inspection or logging unless operated by the mint itself and configured for stateless processing.
- **Non-Collusion Requirement**: OHTTP's privacy guarantees rely on the relay and mint not colluding (working together to deanonymize users). For this reason, the relay and mint SHOULD be operated by different entities that do not share information about user traffic. When the same entity operates both the relay and mint, or when operators collude, they can correlate encrypted traffic patterns with mint operations, completely undermining the privacy benefits of OHTTP.
- **Purpose Discovery Privacy**: The purpose discovery mechanism reveals gateway capabilities but does not compromise OHTTP privacy. Probing requests do not require authentication and do not reveal client identity. HTTPS SHOULD be used for gateway probing to prevent tampering.
- **Purpose String Uniqueness**: The UUID in the Cashu purpose string (`2253f530-151f-4800-a58e-c852a8dc8cff`) prevents accidental collisions with other protocols that may use similar purpose discovery mechanisms.
- Mints MUST publish valid OHTTP key configurations and rotate them as needed per the OHTTP specification.
- Wallets SHOULD validate URLs derived from mint info to avoid SSRF or downgrade attacks. If both direct HTTP and OHTTP are available, wallets SHOULD prefer OHTTP when a relay/gateway is configured and keys can be fetched successfully.

## Mint info setting

Mints advertise OHTTP support in the `nuts` section of the [NUT‑06][06] `GetInfoResponse`.

```json
{
"nuts": {
"26": {
"supported": true,
"gateway_url": "https://ohttp.example.com"
}
}
}
```

Fields:

- `supported` (bool): Set to `true` when the mint supports OHTTP.
- `gateway_url` (str|null, optional): Base URL of the OHTTP gateway to use for key discovery (and, by convention, for the OHTTP gateway endpoint). If omitted or `null`, clients SHOULD assume the gateway is available on the mint's own origin.

[06]: 06.md