Merge pull request #93 from pippellia-btc/update-auth-tokens

Usage of X-SHA-256 and other cleanups in BUD-11
This commit is contained in:
hzrd149
2026-03-07 12:18:46 -03:00
committed by GitHub
7 changed files with 83 additions and 199 deletions
+1 -8
View File
@@ -36,19 +36,12 @@ 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/11.md) (see [BUD-02](./buds/02.md#upload-authorization))
- 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/11.md) (see [BUD-02](./buds/02.md#list-authorization))
- `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/11.md) (see [BUD-02](./buds/02.md#delete-authorization))
- `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob)
- `Authentication`: Signed [nostr event](./buds/11.md) (see [BUD-02](./buds/02.md#upload-authorization))
- `HEAD /media` [BUD-05](./buds/05.md#head-media)
- `PUT /media` [BUD-05](./buds/05.md#put-media)
- `Authentication`: Signed [nostr event](./buds/11.md) (see [BUD-05](./buds/05.md#upload-authorization))
- `PUT /report` [BUD-09](./buds/09.md)
## Event kinds
+3 -47
View File
@@ -11,14 +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.
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
@@ -52,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 first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then perform the following additional checks:
1. A `t` tag MUST be present and set to `get`
2. The authorization token MUST contain either a `server` tag (limiting the token to specific servers) or MUST contain at least one `x` tag matching the sha256 hash of the blob being retrieved (scoping the token to specific blob hashes). see [BUD-11](./11.md#tag-scoping).
If the client did not send an `Authorization` header the server must respond with the appropriate HTTP status code `401` (Unauthorized)
Example authorization token 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 authorization token 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", "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
+10 -76
View File
@@ -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 require an authorization token when uploading blobs. The server MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then perform the following additional checks:
1. The `t` tag MUST be set to `upload`
2. The authorization token MUST contain at least one `x` tag matching the sha256 hash of the body of the request. The `x` tag scopes the token to specific blob hashes (see [BUD-11](./11.md#tag-scoping)).
Example authorization token:
```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)
@@ -90,26 +66,7 @@ Servers MAY reject a list request for any reason and MUST respond with the appro
### List Authorization
The server MAY require a `list` authorization token when listing blobs uploaded by the pubkey. If a server requires authorization it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then it MUST perform the following additional checks:
1. The `t` tag MUST be set to `list`
Example authorization token:
```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,27 +76,4 @@ Servers MAY reject a delete request for any reason and SHOULD respond with the a
### Delete Authorization
Servers MAY require a `delete` authorization token when deleting blobs. If a server requires authorization it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then MUST perform the following additional checks:
1. The `t` tag MUST be set to `delete`
2. MUST contain at least one `x` tag matching the sha256 hash of the blob being deleted.
**Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to delete multiple blobs.**
Example authorization token:
```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.**
+1 -6
View File
@@ -32,12 +32,7 @@ Servers MAY reject a mirror request for any reason and MUST respond with the app
### Upload Authorization
Servers MAY require an `upload` authorization token when mirroring blobs. The server MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then MUST perform the following additional checks:
1. The `t` tag MUST be set to `upload`
2. The authorization token MUST contain at least one `x` tag matching the sha256 hash of the downloaded blob. The `x` tag scopes the token to specific blob hashes (see [BUD-11](./11.md#tag-scoping)).
**Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to mirror multiple blobs.**
Servers MAY require authorization when mirroring blobs as defined by [BUD-11](./11.md#endpoint-authorization-requirements).
## Example Flow
+12 -18
View File
@@ -8,20 +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 token to identify the uploader. If a server requires a `media` authorization token it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then MUST perform the following additional checks:
1. The `t` tag MUST be set to `media`
2. The authorization token 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
@@ -29,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 token 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
View File
@@ -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 token using the `Authorization` header similar to what is used in the [`PUT /upload`](./02.md#upload-authorization) 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
+53 -39
View File
@@ -4,74 +4,88 @@
`draft` `optional`
Defines the authorization token format used by blossom servers to identify users. Authorization tokens are optional and servers MAY require them for various endpoints.
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 events proving to a server that the user (`pubkey`) has permitted an application to take an action on their behalf.
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.
The authorization token MUST be a nostr event of kind `24242` and have a `t` tag with a verb of `get`, `upload`, `list`, `delete`, or `media`
All authorization tokens:
Authorization tokens MUST have the `content` set to a human readable string explaining intended use. For example `Upload Blob`, `Delete old blobs`, `List Images`, etc
- 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.
All authorization tokens 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 [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 domain name only (e.g., `cdn.example.com`), not a full URL.
- **`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 blob hashes (similar to how `server` scopes to servers). 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.
- **`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": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb",
"pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e",
"id": "7a1735c3852cf3f374edae4b2af2ee18e750e6dec583e19c4795d3b179af6d17",
"kind": 24242,
"content": "Upload bitcoin.pdf",
"created_at": 1708773959,
"pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"created_at": 1772019044,
"tags": [
["t", "upload"],
// Authorization tokens MAY have multiple "x" tags.
["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
["expiration", "1708858680"]
["t","upload"],
["expiration","1708858680"],
// Authorization token MAY have multiple "x" tags
["x","b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
],
"sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f"
"content": "",
"sig": "4b57c22b1797b109530ffe5d04cabac468b1a5942873a5141334ecbc77694fc968a1b941979ba13602fceb1dad8014ab6469c6ae9cef0b5668cc23ad1449e103"
}
```
## Base validation
## HTTP Authorization Header
Servers must perform the following checks in order to validate the authorization token
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
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. If `server` tags are present, the server MUST verify that its domain name is present in at least one `server` tag. If no `server` tags are present, the token is valid for all servers.
## HTTP Authorization header
Using the `Authorization` HTTP header, the authorization token (kind `24242`) MUST be encoded as Base64 URL-safe without padding (Base64url, as used by JWTs) and use the Authorization scheme Nostr
Example HTTP Authorization header:
Example HTTP Authorization Header:
```
Authorization: Nostr eyJpZCI6IjhlY2JkY2RkNTMyOTIwMDEwNTUyNGExNDI4NzkxMzg4MWIzOWQxNDA5ZDhiOTBjY2RiNGI0M2Y4ZjBmYzlkMGMiLCJwdWJrZXkiOiI5ZjBjYzE3MDIzYjJjZjUwOWUwZjFkMzA1NzkzZDIwZTdjNzIyNzY5MjhmZDliZjg1NTM2ODg3YWM1NzBhMjgwIiwiY3JlYXRlZF9hdCI6MTcwODc3MTIyNywia2luZCI6MjQyNDIsInRhZ3MiOltbInQiLCJnZXQiXSxbImV4cGlyYXRpb24iLCIxNzA4ODU3NTQwIl1dLCJjb250ZW50IjoiR2V0IEJsb2JzIiwic2lnIjoiMDJmMGQyYWIyM2IwNDQ0NjI4NGIwNzFhOTVjOThjNjE2YjVlOGM3NWFmMDY2N2Y5NmNlMmIzMWM1M2UwN2I0MjFmOGVmYWRhYzZkOTBiYTc1NTFlMzA4NWJhN2M0ZjU2NzRmZWJkMTVlYjQ4NTFjZTM5MGI4MzI4MjJiNDcwZDIifQ==
Authorization: Nostr ewogICJpZCI6ICI3YTE3MzVjMzg1MmNmM2YzNzRlZGFlNGIyYWYyZWUxOGU3NTBlNmRlYzU4M2UxOWM0Nzk1ZDNiMTc5YWY2ZDE3IiwKICAia2luZCI6IDI0MjQyLAogICJwdWJrZXkiOiAiNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCIsCiAgImNyZWF0ZWRfYXQiOiAxNzcyMDE5MDQ0LAogICJ0YWdzIjogWwogICAgWyJ0IiwidXBsb2FkIl0sCiAgICBbImV4cGlyYXRpb24iLCIxNzA4ODU4NjgwIl0sCiAgICAvLyBBdXRob3JpemF0aW9uIHRva2VuIE1BWSBoYXZlIG11bHRpcGxlICJ4IiB0YWdzCiAgICBbIngiLCJiMTY3NDE5MWE4OGVjNWNkZDczM2U0MjQwYTgxODAzMTA1ZGM0MTJkNmM2NzA4ZDUzYWI5NGZjMjQ4ZjRmNTUzIl0sCiAgXSwKICAiY29udGVudCI6ICIiLAogICJzaWciOiAiNGI1N2MyMmIxNzk3YjEwOTUzMGZmZTVkMDRjYWJhYzQ2OGIxYTU5NDI4NzNhNTE0MTMzNGVjYmM3NzY5NGZjOTY4YTFiOTQxOTc5YmExMzYwMmZjZWIxZGFkODAxNGFiNjQ2OWM2YWU5Y2VmMGI1NjY4Y2MyM2FkMTQ0OWUxMDMiCn0
```
## Endpoint-specific requirements (example)
## Validation
Individual endpoints may extend the base validation with additional requirements. The following are examples of how endpoints use authorization tokens:
To validate an authorization token, a server MUST perform the following checks:
- **`/upload`** ([BUD-02](./02.md#upload-authorization)): May requires at least one `x` tag matching the sha256 hash of the blob being uploaded
- **`DELETE /<sha256>`** ([BUD-02](./02.md#delete-authorization)): May requires at least one `x` tag matching the sha256 hash of the blob being deleted
- **`PUT /media`** ([BUD-05](./05.md#upload-authorization)): May requires at least one `x` tag matching the sha256 hash of the media being uploaded
- **`GET /<sha256>`** ([BUD-01](./01.md#get-authorization)): May require either a `server` tag or at least one `x` tag matching the sha256 hash of the blob being retrieved
- **`GET /list/<pubkey>`** ([BUD-02](./02.md#list-authorization)): May require a `server` tag limiting the token to specific servers
- **`PUT /mirror`** ([BUD-04](./04.md#put-mirror---mirror-blob)): May requires at least one `x` tag matching the sha256 hash of the blob being mirrored
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.
See the respective BUD documents for the exact requirements for each endpoint. All endpoints that accept authorization tokens MUST perform the base validation checks defined above before performing any endpoint-specific checks.
## 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.