-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ucan invocation handler (#133)
### Context To enable the gateway to serve content from a specific space, the space owner must delegate the `space/content/serve/*` capability to the Gateway. This delegation ensures the Gateway has the authority to serve the content and log egress events accurately. This PR introduces a new handler to process POST requests to the server's root path. The handler acts as a UCAN Invocation handler, processing `access/delegate` invocations and extracting relevant delegation proofs. If a delegation proof is valid, it is stored in Cloudflare KV, allowing other handlers to retrieve and verify the proof to determine whether content should be served and egress logged. Note: It doesn't cover the token verification. ### Main Changes #### **New Functionality** - Added `withUcanInvocationHandler.js` to process `access/delegate` invocations: - Validates delegation proofs. - Stores valid proofs in a Cloudflare KV namespace dedicated to `content serve` delegations. - Feature Flag: `FF_DELEGATIONS_STORAGE_ENABLED` if enabled, the new `withDelegationsStorage.js` handler will be used to find delegations in KV, and the existing `withDelegationsStubs.js` will be disabled. ### Related Issues - storacha/project-tracking#158 - storacha/project-tracking#160
- Loading branch information
Showing
24 changed files
with
737 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
### Gateway Content Serve Authorization Flow | ||
|
||
```mermaid | ||
flowchart TD | ||
subgraph Client Side | ||
A[User] -->|Creates Space & Authorizes Gateway| B[w3up-client] | ||
end | ||
subgraph Cloudflare Freeway Worker | ||
C[Ucanto Server] | ||
F[Content Server] | ||
end | ||
subgraph Cloudflare KV Store | ||
D[Content Serve Delegations] | ||
end | ||
B -->|UCAN access/delegate| C | ||
C -->E[UCAN Invocation Handler] | ||
E -->|Stores Valid Delegation| D | ||
F -->|Retrieves Delegation| D[Content Serve Delegations] | ||
``` | ||
|
||
### Explanation | ||
1. **User Interaction** | ||
- The user interacts with the `w3up-client` to create a space and authorize the gateway to serve content. | ||
|
||
2. **UCAN Invocation** | ||
- The `w3up-client` sends a UCAN invocation `access/delegate` to the Ucanto Server, providing the delegation details (`{ space, proofs }`). | ||
- The request is processed by the UCAN Invocation Handler in the Cloudflare Freeway Worker. | ||
|
||
3. **Validation Steps** | ||
- It validates that the delegation matches the expected capability (`space/content/serve/*`). | ||
- It ensures the proof chain is valid. | ||
|
||
4. **Storing Delegation** | ||
- After successful validation, the delegation is stored in the KV Store (`Content Serve Delegations Storage`) for further use. | ||
|
||
5. **Content Server Retrieval** | ||
- The Freeway Worker retrieves the validated delegations from the KV Store to serve content for authorized spaces. | ||
|
||
|
||
### Key Considerations | ||
- **Mitigating DoS Attacks** | ||
- By verifying that the space is provisioned before accepting the delegation, we can reduce the risk of abuse from unauthorized or irrelevant requests. | ||
- We still need to implement this verification in another iteration. | ||
- **Efficiency** | ||
- This additional validation ensures only relevant delegations are processed and stored, minimizing resource waste. | ||
- **Implementation** | ||
- Adding a check against the space provisioning status in the `Ucanto Server` can be done efficiently by querying the space registry or relevant provisioning database. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,23 @@ | ||
import * as Ucanto from '@ucanto/interface' | ||
import { Context as MiddlewareContext } from '@web3-storage/gateway-lib' | ||
|
||
export interface DelegationsStorageContext extends MiddlewareContext { | ||
delegationsStorage: DelegationsStorage | ||
} | ||
|
||
import { SpaceDID } from '@web3-storage/capabilities/types' | ||
export interface DelegationProofsContext extends MiddlewareContext { | ||
/** | ||
* The delegation proofs to use for the egress record | ||
* The proofs must be valid for the space and the owner of the space | ||
* must have delegated the right to the Gateway to serve content and record egress traffic. | ||
* The `space/content/serve/*` capability must be granted to the Gateway Web DID. | ||
*/ | ||
delegationProofs: Ucanto.Delegation[] | ||
delegationProofs: Ucanto.Delegation<Ucanto.Capabilities>[] | ||
} | ||
|
||
export interface SpaceContext extends MiddlewareContext { | ||
space: Ucanto.DID | null | ||
} | ||
|
||
// TEMP: https://github.com/storacha/blob-fetcher/pull/13/files | ||
declare module '@web3-storage/blob-fetcher' { | ||
interface Site { | ||
space?: Ucanto.DID | ||
} | ||
} | ||
|
||
// TEMP | ||
|
||
export interface Query { | ||
audience?: Ucanto.DID | ||
can: string | ||
with: Ucanto.Resource | ||
} | ||
|
||
export interface DelegationsStorage { | ||
/** | ||
* find all items that match the query | ||
* The SpaceDID of the space that is authorized to serve the content from. | ||
* If the space is not authorized, the request is considered a legacy request - which is served by default. | ||
* The egress is not recorded for legacy requests because the space is unknown. | ||
* Eventually, legacy requests will be aggressively throttled, forcing the users to migrate to authorized spaces. | ||
* Then this field will become required and the legacy behavior will be removed. | ||
*/ | ||
find: ( | ||
query: Query | ||
) => Promise<Ucanto.Result<Ucanto.Delegation[], Ucanto.Failure>> | ||
space?: SpaceDID | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.