mirror of
https://github.com/hzrd149/blossom.git
synced 2026-08-08 23:34:41 +00:00
Merge pull request #91 from hzrd149/update-auth-tokens
BUD-11 Authorization
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 🌸 Blossom - Blobs stored simply on mediaservers
|
||||
|
||||
Blossom uses [nostr](https://github.com/nostr-protocol/nostr) public / private keys for identities. Users are expected to sign authorization events to prove their identity when interacting with servers
|
||||
Blossom uses [nostr](https://github.com/nostr-protocol/nostr) public / private keys for users identities.
|
||||
|
||||
## What is it?
|
||||
|
||||
@@ -27,6 +27,7 @@ BUDs or **Blossom Upgrade Documents** are short documents that outline an additi
|
||||
- [BUD-08: Nostr File Metadata Tags](./buds/08.md)
|
||||
- [BUD-09: Blob Report](./buds/09.md)
|
||||
- [BUD-10: Blossom URI Schema](./buds/10.md)
|
||||
- [BUD-11: Nostr Authorization](./buds/11.md)
|
||||
|
||||
## Endpoints
|
||||
|
||||
@@ -35,26 +36,19 @@ Blossom Servers expose a few endpoints for managing blobs
|
||||
- `GET /<sha256>` (optional file `.ext`) [BUD-01](./buds/01.md#get-sha256---get-blob)
|
||||
- `HEAD /<sha256>` (optional file `.ext`) [BUD-01](./buds/01.md#head-sha256---has-blob)
|
||||
- `PUT /upload` [BUD-02](./buds/02.md#put-upload---upload-blob)
|
||||
- `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required)
|
||||
- Return a blob descriptor
|
||||
- `HEAD /upload` [BUD-06](./buds/06.md#head-upload---upload-requirements)
|
||||
- `GET /list/<pubkey>` [BUD-02](./buds/02.md#get-listpubkey---list-blobs-unrecommended) _(optional, unrecommended)_
|
||||
- Returns an array of blob descriptors
|
||||
- `Authentication` _(optional)_: Signed [nostr event](./buds/02.md#list-authorization-optional)
|
||||
- `GET /list/<pubkey>` [BUD-02](./buds/02.md#get-listpubkey---list-blobs-unrecommended) _(unrecommended)_
|
||||
- `DELETE /<sha256>` [BUD-02](./buds/02.md#delete-sha256---delete-blob)
|
||||
- `Authentication`: Signed [nostr event](./buds/02.md#delete-authorization-required)
|
||||
- `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob)
|
||||
- `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required)
|
||||
- `HEAD /media` [BUD-05](./buds/05.md#head-media)
|
||||
- `PUT /media` [BUD-05](./buds/05.md#put-media)
|
||||
- `Authentication`: Signed [nostr event](./buds/05.md#upload-authorization)
|
||||
- `PUT /report` [BUD-09](./buds/09.md)
|
||||
|
||||
## Event kinds
|
||||
|
||||
| kind | description | BUD |
|
||||
| ------- | ------------------- | ------------------ |
|
||||
| `24242` | Authorization event | [01](./buds/01.md) |
|
||||
| `24242` | Authorization token | [11](./buds/11.md) |
|
||||
| `10063` | User Server List | [03](./buds/03.md) |
|
||||
|
||||
## License
|
||||
|
||||
+3
-96
@@ -11,63 +11,13 @@ _All pubkeys MUST be in hex format_
|
||||
Servers MUST set the `Access-Control-Allow-Origin: *` header on all responses to ensure compatibility with applications hosted on other domains.
|
||||
|
||||
For [preflight](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests) (`OPTIONS`) requests,
|
||||
servers MUST also set, at minimum, the `Access-Control-Allow-Headers: Authorization, *` and `Access-Control-Allow-Methods: GET, HEAD, PUT,
|
||||
DELETE` headers.
|
||||
servers MUST also set, at minimum, the `Access-Control-Allow-Headers: Authorization, *` and `Access-Control-Allow-Methods: GET, HEAD, PUT, DELETE` headers.
|
||||
|
||||
The header `Access-Control-Max-Age: 86400` MAY be set to cache the results of a preflight request for 24 hours.
|
||||
|
||||
## Error responses
|
||||
|
||||
Every time a server sends an error response (HTTP status codes >=400), it may include a human-readable header `X-Reason` that can be displayed to the user.
|
||||
|
||||
## Authorization events
|
||||
|
||||
Authorization events are used to identify the users to the server
|
||||
|
||||
Authorization events must be generic and must NOT be scoped to specific servers. This allows pubkeys to sign a single event and interact the same way with multiple servers.
|
||||
|
||||
Events MUST be kind `24242` and have a `t` tag with a verb of `get`, `upload`, `list`, or `delete`
|
||||
|
||||
Events MUST have the `content` set to a human readable string explaining to the user what the events intended use is. For example `Upload Blob`, `Delete dog-picture.png`, `List Images`, etc
|
||||
|
||||
All events MUST have a [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) `expiration` tag set to a unix timestamp at which the event should be considered expired.
|
||||
|
||||
Authorization events MAY have multiple `x` tags for endpoints that require a sha256 hash.
|
||||
|
||||
Example event:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb",
|
||||
"pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e",
|
||||
"kind": 24242,
|
||||
"content": "Upload bitcoin.pdf",
|
||||
"created_at": 1708773959,
|
||||
"tags": [
|
||||
["t", "upload"],
|
||||
// Authorization events MAY have multiple "x" tags.
|
||||
["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
|
||||
["expiration", "1708858680"]
|
||||
],
|
||||
"sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f"
|
||||
}
|
||||
```
|
||||
|
||||
Servers must perform the following checks in order to validate the event
|
||||
|
||||
1. The `kind` must be `24242`
|
||||
2. `created_at` must be in the past
|
||||
3. The `expiration` tag must be set to a Unix timestamp in the future
|
||||
4. The `t` tag must have a verb matching the intended action of the endpoint
|
||||
5. Additional checks for specific endpoints. `/upload`, `/delete`, etc
|
||||
|
||||
Using the `Authorization` HTTP header, the kind `24242` event MUST be base64 encoded and use the Authorization scheme Nostr
|
||||
|
||||
Example HTTP Authorization header:
|
||||
|
||||
```
|
||||
Authorization: Nostr eyJpZCI6IjhlY2JkY2RkNTMyOTIwMDEwNTUyNGExNDI4NzkxMzg4MWIzOWQxNDA5ZDhiOTBjY2RiNGI0M2Y4ZjBmYzlkMGMiLCJwdWJrZXkiOiI5ZjBjYzE3MDIzYjJjZjUwOWUwZjFkMzA1NzkzZDIwZTdjNzIyNzY5MjhmZDliZjg1NTM2ODg3YWM1NzBhMjgwIiwiY3JlYXRlZF9hdCI6MTcwODc3MTIyNywia2luZCI6MjQyNDIsInRhZ3MiOltbInQiLCJnZXQiXSxbImV4cGlyYXRpb24iLCIxNzA4ODU3NTQwIl1dLCJjb250ZW50IjoiR2V0IEJsb2JzIiwic2lnIjoiMDJmMGQyYWIyM2IwNDQ0NjI4NGIwNzFhOTVjOThjNjE2YjVlOGM3NWFmMDY2N2Y5NmNlMmIzMWM1M2UwN2I0MjFmOGVmYWRhYzZkOTBiYTc1NTFlMzA4NWJhN2M0ZjU2NzRmZWJkMTVlYjQ4NTFjZTM5MGI4MzI4MjJiNDcwZDIifQ==
|
||||
```
|
||||
Every time a server sends an error response (HTTP status codes >=400), it MAY include a human-readable header `X-Reason` that can be displayed to the user.
|
||||
|
||||
## Endpoints
|
||||
|
||||
@@ -101,50 +51,7 @@ include a file extension in the URL that reflects the blob type (e.g. `.bin`, `.
|
||||
|
||||
### Get Authorization (optional)
|
||||
|
||||
The server may optionally require authorization when retrieving blobs from the `GET /<sha256>` endpoint
|
||||
|
||||
In this case, the server MUST perform additional checks on the authorization event
|
||||
|
||||
1. A `t` tag MUST be present and set to `get`
|
||||
2. The event MUST contain either a `server` tag containing the full URL to the server or MUST contain at least one `x` tag matching the sha256 hash of the blob being retrieved
|
||||
|
||||
If the client did not send an `Authorization` header the server must respond with the appropriate HTTP status code `401` (Unauthorized)
|
||||
|
||||
Example event for retrieving a single blob:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "06d4842b9d7f8bf72440471704de4efa9ef8f0348e366d097405573994f66294",
|
||||
"pubkey": "ec0d11351457798907a3900fe465bfdc3b081be6efeb3d68c4d67774c0bc1f9a",
|
||||
"kind": 24242,
|
||||
"content": "Get bitcoin.pdf",
|
||||
"created_at": 1708771927,
|
||||
"tags": [
|
||||
["t", "get"],
|
||||
["expiration", "1708857340"],
|
||||
["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"]
|
||||
],
|
||||
"sig": "22ecb5116ba143e4c3d6dc4b53d549aed6970ec455f6d25d145e0ad1fd7c0e26c465b2e92d5fdf699c7050fa43e6a41f087ef167208d4f06425f61548168fd7f"
|
||||
}
|
||||
```
|
||||
|
||||
Example event for retrieving multiple blobs from single server:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "d9484f18533d5e36f000f902a45b15a7eecf5fbfcb046789756d57ea87115dc5",
|
||||
"pubkey": "b5f07faa8d3529f03bd898a23dfb3257bab8d8f5490777c46076ff9647e205dc",
|
||||
"kind": 24242,
|
||||
"content": "Get blobs from example.com",
|
||||
"created_at": 1708771927,
|
||||
"tags": [
|
||||
["t", "get"],
|
||||
["expiration", "1708857340"],
|
||||
["server", "https://cdn.example.com/"]
|
||||
],
|
||||
"sig": "e402ade78e1714d40cd6bd3091bc5f4ada8e904e90301b5a2b9b5f0b6e95ce908d4f22b15e9fb86f8268a2131f8adbb3d1f0e7e7afd1ab0f4f08acb15822a999"
|
||||
}
|
||||
```
|
||||
Servers MAY require authorization when retrieving blobs, as defined by [BUD-11](./11.md#endpoint-authorization-requirements).
|
||||
|
||||
## HEAD /sha256 - Has Blob
|
||||
|
||||
|
||||
+12
-84
@@ -20,7 +20,7 @@ A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, a
|
||||
|
||||
Servers MUST include a file extension in the URL in the `url` field to allow clients to easily embed the URL in social posts or other content
|
||||
|
||||
Servers MAY include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support
|
||||
Servers MAY include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -36,45 +36,21 @@ Example:
|
||||
|
||||
## PUT /upload - Upload Blob
|
||||
|
||||
The `PUT /upload` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` and `Content-Length` headers to get the MIME type and size of the data
|
||||
The `PUT /upload` endpoint MUST accept binary data in the request body.
|
||||
The server MUST NOT modify the blob in any way and MUST compute the sha256 hash over the exact bytes received. This requirement ensures that users can re-upload blobs to other servers without discrepancies.
|
||||
|
||||
The endpoint MUST NOT modify the blob in any way and SHOULD return the exact same sha256 that was uploaded. This is critical to allow users to re-upload their blobs to new servers
|
||||
Clients SHOULD include `Content-Type` and `Content-Length` headers specifying the MIME type and size of the data. Clients MAY provide an `X-SHA-256` header containing the lowercase hex-encoded sha256 of the request body. A server MAY use this value to enforce rejection policies or perform authorization checks prior to persisting the blob.
|
||||
|
||||
The endpoint MUST return a [Blob Descriptor](#blob-descriptor) if the upload was successful or an error object if it was not
|
||||
|
||||
Servers MAY reject an upload for any reason and SHOULD respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
||||
On success, the endpoint MUST respond with a `2xx` status code with a [Blob Descriptor](#blob-descriptor) in the response body.
|
||||
On failure, the endpoint MUST return an appropriate `4xx` status code and an error message explaining the reason for the rejection.
|
||||
|
||||
### File extension normalization (Optional)
|
||||
|
||||
When storing blobs, servers MAY normalise the file extension to a standard format (e.g. `.pdf`, `.png`, etc.) based on
|
||||
the MIME type of the blob. This can be especially useful when the `GET /<sha256>` endpoint is redirected to an external
|
||||
URL (see the [proxying and redirection section from BUD-01](./01.md#proxying-and-redirection-optional)), as external
|
||||
servers may rely on the file extension to serve the blob correctly.
|
||||
When storing blobs, servers MAY normalise the file extension to a standard format (e.g. `.pdf`, `.png`, etc.) based on the MIME type of the blob. This can be especially useful when the `GET /<sha256>` endpoint is redirected to an external URL (see the [proxying and redirection section from BUD-01](./01.md#proxying-and-redirection-optional)), as external servers may rely on the file extension to serve the blob correctly.
|
||||
|
||||
### Upload Authorization (Optional)
|
||||
|
||||
Servers MAY accept an authorization event when uploading blobs and SHOULD perform additional checks
|
||||
|
||||
1. The `t` tag MUST be set to `upload`
|
||||
2. The authorization event MUST contain at least one `x` tag matching the sha256 hash of the body of the request
|
||||
|
||||
Example Authorization event:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb",
|
||||
"pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e",
|
||||
"kind": 24242,
|
||||
"content": "Upload bitcoin.pdf",
|
||||
"created_at": 1708773959,
|
||||
"tags": [
|
||||
["t", "upload"],
|
||||
["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
|
||||
["expiration", "1708858680"]
|
||||
],
|
||||
"sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f"
|
||||
}
|
||||
```
|
||||
Servers MAY require authorization when uploading blobs, as defined by [BUD-11](./11.md#endpoint-authorization-requirements).
|
||||
|
||||
## GET /list/pubkey - List Blobs (Unrecommended)
|
||||
|
||||
@@ -88,30 +64,9 @@ The endpoint MAY support `since` and `until` query parameters to filter the list
|
||||
|
||||
Servers MAY reject a list request for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
||||
|
||||
### List Authorization (optional)
|
||||
### List Authorization
|
||||
|
||||
The server MAY optionally require Authorization when listing blobs uploaded by the pubkey
|
||||
|
||||
In this case the server MUST perform additional checks on the authorization event
|
||||
|
||||
1. The `t` tag MUST be set to `list`
|
||||
|
||||
Example Authorization event:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "cbb1cab9566355bfdf04e1f1fc1e655fe903ecc193e8a750092ee53beec2a0e8",
|
||||
"pubkey": "a5fc3654296e6de3cda6ba3e8eba7224fac8b150fd035d66b4c3c1dc2888b8fc",
|
||||
"kind": 24242,
|
||||
"content": "List Blobs",
|
||||
"created_at": 1708772350,
|
||||
"tags": [
|
||||
["t", "list"],
|
||||
["expiration", "1708858680"]
|
||||
],
|
||||
"sig": "ff9c716f8de0f633738036472be553ce4b58dc71d423a0ef403f95f64ef28582ef82129b41d4d0ef64d2338eb4aeeb66dbc03f8b3a3ed405054ea8ecb14fa36c"
|
||||
}
|
||||
```
|
||||
Servers MAY require authorization when listing blobs as defined by [BUD-11](./11.md#endpoint-authorization-requirements).
|
||||
|
||||
## DELETE /sha256 - Delete Blob
|
||||
|
||||
@@ -119,33 +74,6 @@ Servers MUST accept `DELETE` requests to the `/<sha256>` endpoint
|
||||
|
||||
Servers MAY reject a delete request for any reason and SHOULD respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
||||
|
||||
### Delete Authorization (required)
|
||||
### Delete Authorization
|
||||
|
||||
Servers MUST accept an authorization event when deleting blobs
|
||||
|
||||
Servers SHOULD perform additional checks on the authorization event
|
||||
|
||||
1. The `t` tag MUST be set to `delete`
|
||||
2. The authorization event MUST contain at least one `x` tag matching the sha256 hash of the blob being deleted
|
||||
|
||||
When multiple `x` tags are present on the authorization event the server MUST only delete the blob listed in the URL.
|
||||
|
||||
**Multiple `x` tags MUST NOT be interpreted as the user requesting a bulk delete.**
|
||||
|
||||
Example Authorization event:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "a92868bd8ea740706d931f5d205308eaa0e6698e5f8026a990e78ee34ce47fe8",
|
||||
"pubkey": "ae0063dd2c81ec469f2291ac029a19f39268bfc40aea7ab4136d7a858c3a06de",
|
||||
"kind": 24242,
|
||||
"content": "Delete bitcoin.pdf",
|
||||
"created_at": 1708774469,
|
||||
"tags": [
|
||||
["t", "delete"],
|
||||
["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
|
||||
["expiration", "1708858680"]
|
||||
],
|
||||
"sig": "2ba9af680505583e3eb289a1624a08661a2f6fa2e5566a5ee0036333d517f965e0ffba7f5f7a57c2de37e00a2e85fd7999076468e52bdbcfad8abb76b37a94b0"
|
||||
}
|
||||
```
|
||||
Servers MAY require authorization when deleting blobs as defined by [BUD-11](./11.md#endpoint-authorization-requirements). **Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to delete multiple blobs.**
|
||||
|
||||
+7
-9
@@ -19,12 +19,6 @@ Clients MUST pass the URL of the remote blob as a stringified JSON object in the
|
||||
}
|
||||
```
|
||||
|
||||
Clients MAY set the `Authorization` header to an upload authorization event defined in [BUD-02](./02.md#upload-authorization-optional). When using authorization, the event MUST be of type "upload".
|
||||
|
||||
The `/mirror` endpoint MUST download the blob from the specified URL and verify that there is at least one `x` tag in the authorization event matching the sha256 hash of the download blob
|
||||
|
||||
**Multiple `x` tags in the authorization event MUST NOT be interpreted as the user requesting to mirror multiple blobs.**
|
||||
|
||||
The endpoint MUST return a [Blob Descriptor](#blob-descriptor) and a `2xx` status code if the mirroring was successful
|
||||
or a `4xx` status code and error message if it was not.
|
||||
|
||||
@@ -36,11 +30,15 @@ Servers MAY use the `Content-Length` header to determine the size of the blob.
|
||||
|
||||
Servers MAY reject a mirror request for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection.
|
||||
|
||||
### Upload Authorization
|
||||
|
||||
Servers MAY require authorization when mirroring blobs as defined by [BUD-11](./11.md#endpoint-authorization-requirements).
|
||||
|
||||
## Example Flow
|
||||
|
||||
1. Client signs an `upload` authorization event and uploads blob to Server A
|
||||
1. Client signs an `upload` authorization token and uploads blob to Server A
|
||||
1. Server A returns a [Blob Descriptor](./02.md#blob-descriptor) with the `url`
|
||||
1. Client sends the `url` to Server B `/mirror` using the original `upload` authorization event
|
||||
1. Client sends the `url` to Server B `/mirror` using the original `upload` authorization token
|
||||
1. Server B downloads the blob from Server A using the `url`
|
||||
1. Server B verifies the downloaded blob hash matches the `x` tag in the authorization event
|
||||
1. Server B verifies the downloaded blob hash matches the `x` tag in the authorization token
|
||||
1. Server B returns a [Blob Descriptor](./02.md#blob-descriptor)
|
||||
|
||||
+12
-20
@@ -8,22 +8,17 @@ Defines the `PUT /media` endpoint for processing and optimizing media
|
||||
|
||||
## PUT /media
|
||||
|
||||
The `PUT /media` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` and `Content-Length` headers to get the MIME type and size of the media
|
||||
The `PUT /media` endpoint MUST accept binary data in the request body.
|
||||
The server SHOULD perform any optimizations or conversions it deems necessary in order to make the media more suitable for distribution.
|
||||
|
||||
The server should preform any optimizations or conversions it deems necessary in order to make the media more suitable for distribution
|
||||
Clients SHOULD include `Content-Type` and `Content-Length` headers specifying the MIME type and size of the data. Clients MAY provide an `X-SHA-256` header containing the lowercase hex-encoded sha256 of the request body. A server MAY use this value to enforce rejection policies or perform authorization checks prior to persisting the blob.
|
||||
|
||||
The endpoint MUST respond with a `2xx` status and a [blob descriptor](./02.md#blob-descriptor) of the new processed blob
|
||||
|
||||
Servers MAY reject media uploads for any reason and should respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
||||
On success, the endpoint MUST respond with a `2xx` status code with a [Blob Descriptor](#blob-descriptor) in the response body.
|
||||
On failure, the endpoint MUST return an appropriate `4xx` status code and an error message explaining the reason for the rejection.
|
||||
|
||||
### Upload Authorization
|
||||
|
||||
Servers MAY require a `media` [authorization event](./02.md#upload-authorization-required) to identify the uploader
|
||||
|
||||
If a server requires a `media` authorization event it MUST perform the following checks
|
||||
|
||||
1. The `t` tag MUST be set to `media`
|
||||
2. MUST contain at least one `x` tag matching the sha256 hash of the body of the request
|
||||
Servers MAY require authorization when processing media as defined by [BUD-11](./11.md#endpoint-authorization-requirements).
|
||||
|
||||
## HEAD /media
|
||||
|
||||
@@ -31,18 +26,15 @@ Servers MUST respond to `HEAD` requests on the `/media` endpoint in a similar wa
|
||||
|
||||
## Limitations
|
||||
|
||||
This endpoint is intentionally limited to optimizing a single blob with the goal of making it easier to distribute
|
||||
The goal of this endpoint is to provide a simple "trusted" optimization endpoint clients can use to optimize media for distribution.
|
||||
How the blob is optimized is the sole responsibility of the server and the client should have no say in what optimization process is used.
|
||||
|
||||
How the blob is optimized is the sole responsibility of the server and the client should have no say in what optimization process is used
|
||||
|
||||
The goal of this endpoint is to provide a simple "trusted" optimization endpoint clients can use to optimize media for distribution
|
||||
|
||||
If a longer optimization or transformation process is needed, or if the client needs to specify how a blob should be transformed. there are other tools and protocol that should be used.
|
||||
If a longer optimization or transformation process is needed, or if the client needs to specify how a blob should be transformed, other protocols should be used.
|
||||
|
||||
## Client Implementation
|
||||
|
||||
Clients MAY let a user selected a "trusted processing" server for uploading images or short videos
|
||||
Clients MAY let a user selected a "trusted processing" server for uploading images or short videos.
|
||||
|
||||
Once a server has been selected, the client uploads the original media to the `/media` endpoint of the trusted server and get the optimized blob back
|
||||
Once a server has been selected, the client uploads the original media to the `/media` endpoint of the trusted server and get the optimized blob back.
|
||||
|
||||
Then the client can ask the user to sign another `upload` authorization event for the new optimized blob and call the `/mirror` endpoint on other servers to distribute the blob
|
||||
Then the client can call the `/mirror` endpoint on other servers to distribute the blob.
|
||||
|
||||
+3
-5
@@ -8,19 +8,17 @@ Defines how clients can verify if the upload can be completed before sending the
|
||||
|
||||
## HEAD /upload - Upload requirements
|
||||
|
||||
The `HEAD /upload` endpoint MUST use the `X-SHA-256`, `X-Content-Type` and `X-Content-Length` headers sent by client to get the SHA-256 hash, MIME type and size of the blob that will be uploaded, returning a HTTP status code and a custom header `X-Reason` to indicate some human readable message about the upload requirements.
|
||||
The `HEAD /upload` endpoint MUST use the `X-SHA-256`, `X-Content-Type` and `X-Content-Length` headers sent by client to get the sha256 hash, MIME type and size of the blob that will be uploaded, returning a HTTP status code and a custom header `X-Reason` to indicate some human readable message about the upload requirements.
|
||||
|
||||
### Headers
|
||||
|
||||
- `X-SHA-256`: A string that represents the blob's SHA-256 hash.
|
||||
- `X-SHA-256`: A lowercase hex-encoded sha256 string that represents the blob's hash.
|
||||
- `X-Content-Length`: An integer that represents the blob size in bytes.
|
||||
- `X-Content-Type`: A string that specifies the blob's MIME type, like `application/pdf` or `image/png`.
|
||||
|
||||
### Upload Authorization
|
||||
|
||||
The `HEAD /upload` endpoint MAY accept an `upload` authorization event using the `Authorization` header similar to what is used in the [`PUT /upload`](./02.md#upload-authorization-required) endpoint
|
||||
|
||||
If the server requires authorization to upload it may respond with the `401` status code, or if authorization was provided and is invalid or not permitted it may respond with `403` status code
|
||||
Servers MAY require authorization for this endpoint as defined by [BUD-11](./11.md#endpoint-authorization-requirements).
|
||||
|
||||
### Examples
|
||||
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
# BUD-11
|
||||
|
||||
## Nostr Authorization
|
||||
|
||||
`draft` `optional`
|
||||
|
||||
Defines the format of the authorization token used by Blossom servers to identify users and by users to authorize actions on those servers. Authorization tokens are optional; servers MAY require them for specific endpoints.
|
||||
|
||||
## Authorization tokens
|
||||
|
||||
Authorization tokens are signed [nostr](https://github.com/nostr-protocol/nips/blob/master/01.md) events of kind `24242` proving to a server that the user (`pubkey`) has permitted an application to take an action on their behalf.
|
||||
|
||||
All authorization tokens:
|
||||
|
||||
- MUST have the `content` set to a human readable string explaining intended use to the user. For example `Upload Blob`, `Delete old blobs`, `List Images`, etc.
|
||||
|
||||
- MUST have a [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) `expiration` tag set to a unix timestamp at which the token should be considered expired.
|
||||
|
||||
- MUST have a `t` tag with a verb of `get`, `upload`, `list`, `delete`, or `media`. The value of the `t` tag MUST correspond to the action performed by the target endpoint, as defined in the section [Endpoint Authorization Requirements](#endpoint-authorization-requirements).
|
||||
|
||||
## Tag scoping
|
||||
|
||||
Authorization tokens MAY include `server` and `x` tags to scope the token to specific servers or blob hashes.
|
||||
|
||||
- **`server` tag**: Limits the token to specific servers by domain name. If no `server` tags are present, the token is valid for all servers. Multiple `server` tags may be present to allow the token to be used on multiple servers. The value MUST be a lowercase domain name only (e.g., `cdn.example.com`), not a full URL.
|
||||
|
||||
- **`x` tag**: Scopes the token to specific lowercase hex-encoded blob hashes. Multiple `x` tags may be present for endpoints that require a sha256 hash. When `x` tags are present, the token is only valid for operations on the specified blob hashes.
|
||||
|
||||
Example authorization token:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"id": "7a1735c3852cf3f374edae4b2af2ee18e750e6dec583e19c4795d3b179af6d17",
|
||||
"kind": 24242,
|
||||
"pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
|
||||
"created_at": 1772019044,
|
||||
"tags": [
|
||||
["t","upload"],
|
||||
["expiration","1708858680"],
|
||||
// Authorization token MAY have multiple "x" tags
|
||||
["x","b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
|
||||
],
|
||||
"content": "",
|
||||
"sig": "4b57c22b1797b109530ffe5d04cabac468b1a5942873a5141334ecbc77694fc968a1b941979ba13602fceb1dad8014ab6469c6ae9cef0b5668cc23ad1449e103"
|
||||
}
|
||||
```
|
||||
|
||||
## HTTP Authorization Header
|
||||
|
||||
Using the `Authorization` HTTP header, the authorization token MUST be encoded as Base64 URL-safe without padding (Base64url, as used by JWTs) and use the Authorization scheme Nostr
|
||||
|
||||
Example HTTP Authorization Header:
|
||||
|
||||
```
|
||||
Authorization: Nostr ewogICJpZCI6ICI3YTE3MzVjMzg1MmNmM2YzNzRlZGFlNGIyYWYyZWUxOGU3NTBlNmRlYzU4M2UxOWM0Nzk1ZDNiMTc5YWY2ZDE3IiwKICAia2luZCI6IDI0MjQyLAogICJwdWJrZXkiOiAiNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCIsCiAgImNyZWF0ZWRfYXQiOiAxNzcyMDE5MDQ0LAogICJ0YWdzIjogWwogICAgWyJ0IiwidXBsb2FkIl0sCiAgICBbImV4cGlyYXRpb24iLCIxNzA4ODU4NjgwIl0sCiAgICAvLyBBdXRob3JpemF0aW9uIHRva2VuIE1BWSBoYXZlIG11bHRpcGxlICJ4IiB0YWdzCiAgICBbIngiLCJiMTY3NDE5MWE4OGVjNWNkZDczM2U0MjQwYTgxODAzMTA1ZGM0MTJkNmM2NzA4ZDUzYWI5NGZjMjQ4ZjRmNTUzIl0sCiAgXSwKICAiY29udGVudCI6ICIiLAogICJzaWciOiAiNGI1N2MyMmIxNzk3YjEwOTUzMGZmZTVkMDRjYWJhYzQ2OGIxYTU5NDI4NzNhNTE0MTMzNGVjYmM3NzY5NGZjOTY4YTFiOTQxOTc5YmExMzYwMmZjZWIxZGFkODAxNGFiNjQ2OWM2YWU5Y2VmMGI1NjY4Y2MyM2FkMTQ0OWUxMDMiCn0
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
To validate an authorization token, a server MUST perform the following checks:
|
||||
|
||||
1. The event `kind` MUST be `24242`.
|
||||
2. The `created_at` timestamp MUST be in the past.
|
||||
3. An `expiration` tag MUST be present and set to a Unix timestamp in the future.
|
||||
4. The `t` tag MUST contain a verb matching the intended action of the endpoint.
|
||||
5. If one or more `server` tags are present, the server MUST verify that its domain name appears in at least one `server` tag.
|
||||
6. If the endpoint requires `x` tags, the server MUST verify that at least one `x` tag matches the blob hash implied by the endpoint.
|
||||
|
||||
## Endpoint Authorization Requirements
|
||||
|
||||
The table below defines, for each endpoint, the required `t` tag action, the implied blob hash (if any), and whether at least one matching `x` tag is required.
|
||||
|
||||
| Endpoint | Required `t` | Implied Blob Hash | `x` Tag Requirement |
|
||||
|----------------------|--------------|-------------------------------|---------------------|
|
||||
| `GET /<sha256>` | `get` | `<sha256>` from the URL | optional |
|
||||
| `HEAD /<sha256>` | `get` | `<sha256>` from the URL | optional |
|
||||
| `PUT /upload` | `upload` | `X-SHA-256` request header | required |
|
||||
| `HEAD /upload` | `upload` | `X-SHA-256` request header | required |
|
||||
| `DELETE /<sha256>` | `delete` | `<sha256>` from the URL | required |
|
||||
| `GET /list/<pubkey>` | `list` | — | not applicable |
|
||||
| `PUT /mirror` | `upload` | SHA-256 of the mirrored blob | required |
|
||||
| `PUT /media` | `media` | `X-SHA-256` request header | required |
|
||||
| `HEAD /media` | `media` | `X-SHA-256` request header | required |
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Unscoped Tokens
|
||||
|
||||
A token that does not include a `server` tag is valid on any Blossom server that accepts it. If intercepted or leaked, such a token can be replayed against other servers for the duration of its validity (until its `expiration`).
|
||||
|
||||
This risk is particularly significant for `delete` tokens. An unscoped `delete` token intercepted from one server can be reused to delete the same blob from any other server where it exists.
|
||||
Reference in New Issue
Block a user