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 are signed nostr 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
contentset to a human readable string explaining intended use to the user. For exampleUpload Blob,Delete old blobs,List Images, etc. -
MUST have a NIP-40
expirationtag set to a unix timestamp at which the token should be considered expired. -
MUST have a
ttag with a verb ofget,upload,list,delete, ormedia. The value of thettag MUST correspond to the action performed by the target endpoint, as defined in the section Endpoint Authorization Requirements.
Authorization tokens MAY include server and x tags to scope the token to specific servers or blob hashes.
-
servertag: Limits the token to specific servers by domain name. If noservertags are present, the token is valid for all servers. Multipleservertags 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. -
xtag: Scopes the token to specific lowercase hex-encoded blob hashes. Multiplextags may be present for endpoints that require a sha256 hash. Whenxtags are present, the token is only valid for operations on the specified blob hashes.
Example 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
Example HTTP Authorization Header:
Authorization: Nostr ewogICJpZCI6ICI3YTE3MzVjMzg1MmNmM2YzNzRlZGFlNGIyYWYyZWUxOGU3NTBlNmRlYzU4M2UxOWM0Nzk1ZDNiMTc5YWY2ZDE3IiwKICAia2luZCI6IDI0MjQyLAogICJwdWJrZXkiOiAiNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCIsCiAgImNyZWF0ZWRfYXQiOiAxNzcyMDE5MDQ0LAogICJ0YWdzIjogWwogICAgWyJ0IiwidXBsb2FkIl0sCiAgICBbImV4cGlyYXRpb24iLCIxNzA4ODU4NjgwIl0sCiAgICAvLyBBdXRob3JpemF0aW9uIHRva2VuIE1BWSBoYXZlIG11bHRpcGxlICJ4IiB0YWdzCiAgICBbIngiLCJiMTY3NDE5MWE4OGVjNWNkZDczM2U0MjQwYTgxODAzMTA1ZGM0MTJkNmM2NzA4ZDUzYWI5NGZjMjQ4ZjRmNTUzIl0sCiAgXSwKICAiY29udGVudCI6ICIiLAogICJzaWciOiAiNGI1N2MyMmIxNzk3YjEwOTUzMGZmZTVkMDRjYWJhYzQ2OGIxYTU5NDI4NzNhNTE0MTMzNGVjYmM3NzY5NGZjOTY4YTFiOTQxOTc5YmExMzYwMmZjZWIxZGFkODAxNGFiNjQ2OWM2YWU5Y2VmMGI1NjY4Y2MyM2FkMTQ0OWUxMDMiCn0
To validate an authorization token, a server MUST perform the following checks:
- The event
kindMUST be24242. - The
created_attimestamp MUST be in the past. - An
expirationtag MUST be present and set to a Unix timestamp in the future. - The
ttag MUST contain a verb matching the intended action of the endpoint. - If one or more
servertags are present, the server MUST verify that its domain name appears in at least oneservertag. - If the endpoint requires
xtags, the server MUST verify that at least onextag matches the blob hash implied by the endpoint.
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 |
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.
{ "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" }