From 35a93ab19f4728236a33800cb6b414d668b24a3d Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 30 Jan 2026 17:55:04 +0000 Subject: [PATCH 1/4] rfc: UCAN Authroized Retrieval via Roundabout --- rfc/roundabout-ucan-retrieval.md | 78 ++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 rfc/roundabout-ucan-retrieval.md diff --git a/rfc/roundabout-ucan-retrieval.md b/rfc/roundabout-ucan-retrieval.md new file mode 100644 index 0000000..98f1122 --- /dev/null +++ b/rfc/roundabout-ucan-retrieval.md @@ -0,0 +1,78 @@ +# UCAN Authorized Retrieval via Roundabout + +Roundabout acts as a redirect service mapping piece CIDs to their actual location URL(s). It does this by looking up their location on the Storacha Network and then sending a HTTP redirect response. + +## Problem + +In the Forge network, retrievals are UCAN authorized, necessitating a HTTP header be added to the request that contains a UCAN authorization permitting retrieval. + +Roundabout currently just redirects to the found URL. There is no provision for UCAN auth. + +## Proposal + +The Spade API provides agents (clients) a [frc58 "manifest"](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md) from which they can build an aggregate piece from. + +It contains the aggregate piece CID, a list of _segment_ piece CIDs, and a URL (multiple supported, in practice only 1). It has the structure: + +```go +type ResponsePieceManifestFR58 struct { + AggPCidV2 string `json:"frc58_aggregate"` + Segments []Segment `json:"piece_list"` +} + +type Segment struct { + PCidV2 string `json:"pcid_v2"` + Sources []string `json:"sources"` // URL(s) the piece may be fetched from +} +``` + +We will augment `Segment` with header(s) that should be added to all HTTP requests: + +```go +type Segment struct { + PCidV2 string `json:"pcid_v2"` + Sources []Source `json:"sources"` // URL(s) the piece may be fetched from +} + +type Source struct { + URL string `json:"url"` + Headers http.Header `json:"headers,omitempty"` +} +``` + +The Spade agent (client) would then add the provided headers to the request to fetch data. + +At the point the manifest is returned the SP is authenticated via the `FIL-SPID-v0` auth scheme used by Spade. Spade will add a UCAN authorization header (e.g. `X-Agent-Message`) for each segment - a `blob/retrieve` invocation for the specific blob to be retrieved. + +It will be necessary for Spade to do the mapping that roundabout currently does, as it needs the blob digest in order to create the `blob/retrieve` delegation. _This process will allow roundabout to be skipped entirely._ as determining the blob digest will also yield the location URL. + +## Other options considered + +### Spade agent knows how to talk UCAN + +Each Spade agent has a DID. + +...but how do we know who is allowed to fetch data? + +### Roundabout response includes invocation + +How to do? Response is a redirect which is just a URL. + +Can we put auth in query string? Probably no. + +...but how do we know who is allowed to fetch data? + +### Signed retrieval URLs + +UCAN authorize a signed URL for retrieval. Can include expiration in signed params. + +1. Roundabout invokes `access/grant`. +2. Storage node delegates `blob/retrieve/url/sign` to roundabout. + +This is cached by roundabout. + +When a request comes in, roundabout invokes `blob/retrieve/url/sign` on the storage node, which returns a time restricted signed URL for accessing a blob. This URL is used as the redirect. + +The advantage is that Spade does not need to know about UCAN at all. + +...but how do we know who is allowed to fetch data? From 28d90bc6158a80f3caed816c14515d92946746ee Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 30 Jan 2026 17:58:42 +0000 Subject: [PATCH 2/4] refactor: tweaks --- rfc/roundabout-ucan-retrieval.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/rfc/roundabout-ucan-retrieval.md b/rfc/roundabout-ucan-retrieval.md index 98f1122..7d30134 100644 --- a/rfc/roundabout-ucan-retrieval.md +++ b/rfc/roundabout-ucan-retrieval.md @@ -26,7 +26,7 @@ type Segment struct { } ``` -We will augment `Segment` with header(s) that should be added to all HTTP requests: +We will augment `Segment` sources with header(s) that should be added to HTTP requests: ```go type Segment struct { @@ -44,35 +44,35 @@ The Spade agent (client) would then add the provided headers to the request to f At the point the manifest is returned the SP is authenticated via the `FIL-SPID-v0` auth scheme used by Spade. Spade will add a UCAN authorization header (e.g. `X-Agent-Message`) for each segment - a `blob/retrieve` invocation for the specific blob to be retrieved. -It will be necessary for Spade to do the mapping that roundabout currently does, as it needs the blob digest in order to create the `blob/retrieve` delegation. _This process will allow roundabout to be skipped entirely._ as determining the blob digest will also yield the location URL. +It will be necessary for Spade to do the mapping that roundabout currently does, as it needs the blob digest in order to create the `blob/retrieve` invocation. _This process will allow roundabout to be skipped entirely._ as determining the blob digest will also yield the location URL. ## Other options considered -### Spade agent knows how to talk UCAN +### Signed retrieval URLs -Each Spade agent has a DID. +UCAN authorize a signed URL for retrieval. Can include expiration in signed params. -...but how do we know who is allowed to fetch data? +1. Roundabout invokes `access/grant`. +2. Storage node delegates `blob/retrieve/url/sign` to roundabout. -### Roundabout response includes invocation +This is cached by roundabout. -How to do? Response is a redirect which is just a URL. +When a request comes in, roundabout invokes `blob/retrieve/url/sign` on the storage node, which returns a time restricted signed URL for accessing a blob. This URL is used as the redirect. -Can we put auth in query string? Probably no. +The advantage is that Spade does not need to know about UCAN at all. ...but how do we know who is allowed to fetch data? -### Signed retrieval URLs +### Roundabout response includes invocation -UCAN authorize a signed URL for retrieval. Can include expiration in signed params. +How to do? Response is a redirect which is just a URL. -1. Roundabout invokes `access/grant`. -2. Storage node delegates `blob/retrieve/url/sign` to roundabout. +Can we put auth in query string? Probably no. -This is cached by roundabout. +...but how do we know who is allowed to fetch data? -When a request comes in, roundabout invokes `blob/retrieve/url/sign` on the storage node, which returns a time restricted signed URL for accessing a blob. This URL is used as the redirect. +### Spade agent knows how to talk UCAN -The advantage is that Spade does not need to know about UCAN at all. +Each Spade agent has a DID. ...but how do we know who is allowed to fetch data? From 6f8f2d1421555e3b1f123ca9f76d6698e55f3ace Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 30 Jan 2026 18:01:20 +0000 Subject: [PATCH 3/4] fix: segments each have urls --- rfc/roundabout-ucan-retrieval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfc/roundabout-ucan-retrieval.md b/rfc/roundabout-ucan-retrieval.md index 7d30134..f27a437 100644 --- a/rfc/roundabout-ucan-retrieval.md +++ b/rfc/roundabout-ucan-retrieval.md @@ -12,7 +12,7 @@ Roundabout currently just redirects to the found URL. There is no provision for The Spade API provides agents (clients) a [frc58 "manifest"](https://github.com/filecoin-project/FIPs/blob/master/FRCs/frc-0058.md) from which they can build an aggregate piece from. -It contains the aggregate piece CID, a list of _segment_ piece CIDs, and a URL (multiple supported, in practice only 1). It has the structure: +It contains the aggregate piece CID, a list of _segment_ piece CIDs, and for each segment, a URL (multiple supported, in practice only 1) the data can be retrieved from. It has the structure: ```go type ResponsePieceManifestFR58 struct { From 9b4da11d15fddd6884eaff908b267731273ca162 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 30 Jan 2026 18:04:13 +0000 Subject: [PATCH 4/4] docs: add note on advantage --- rfc/roundabout-ucan-retrieval.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rfc/roundabout-ucan-retrieval.md b/rfc/roundabout-ucan-retrieval.md index f27a437..33a2aa2 100644 --- a/rfc/roundabout-ucan-retrieval.md +++ b/rfc/roundabout-ucan-retrieval.md @@ -46,6 +46,8 @@ At the point the manifest is returned the SP is authenticated via the `FIL-SPID- It will be necessary for Spade to do the mapping that roundabout currently does, as it needs the blob digest in order to create the `blob/retrieve` invocation. _This process will allow roundabout to be skipped entirely._ as determining the blob digest will also yield the location URL. +The advantage here is that the Spade agent does not need to know how to speak UCAN at all i.e. there is no additional auth needed outside of the existing Spade `FIL-SPID-V0` auth. + ## Other options considered ### Signed retrieval URLs