Blossom on DamageBDD: Share Files with a Verifiable Byte Identity

Give a supporting file an identity readers can check

A signed status event is often only the beginning of a workflow. The useful material may be a report, an image, a recording or another supporting file. Readers need to know that the bytes they retrieved are the bytes the publisher referenced.

DamageBDD's Blossom implementation exposes blobs through their SHA-256 hashes while storing the bytes through its IPFS backend. A descriptor retains the IPFS CID as additional metadata. Nostr-signed authorization controls uploads and deletion of ownership claims.

For a Nostr client developer or operator, this is a concrete integration to try: upload a non-sensitive fixture, retrieve it through its hash address, and independently verify the digest. The 5 October application archive now contains the implementation; the earlier description of Blossom as only reported development scope is superseded by this source review.

The implemented HTTP surface

The module describes support for core BUD-01, BUD-02, BUD-06, BUD-11 and BUD-12 operations. The table records the handlers found in source, not a certification of interoperability with every Blossom client or extension.

Operation Source route What an integrator can evaluate
Retrieve or inspect a blob GET/HEAD /<sha256>[.ext] Matching bytes, headers, range behaviour and CORS
Upload PUT /upload Authorization, transfer limits, digest and returned descriptor
Upload preflight HEAD /upload Hash, size, type and authorization requirements
Remove a claim DELETE /<sha256> The caller's source-scoped ownership claim
List claims GET /list/<pubkey> Configured availability and cursor pagination

The routes are registered by damage_app with the root blob catch-all last, so existing application routes take precedence. Deployment hostnames, TLS, reverse-proxy settings and enabled optional operations still need to be established on the server being integrated.

Authorization is bound to the operation

The verifier handles kind-24242 Nostr authorization events. It checks event shape, public key, creation time, expiration, action, applicable server/hash scope and signature. Parsing and tag sizes are bounded. The implementation accepts standard and URL-safe Base64 encodings, with or without padding, for the transport wrapper.

The upload path enforces declared and actual transfer constraints, computes SHA-256 and checks the authorization's applicable hash scope before persisting the object and claim. This makes useful refusal cases available for a client pilot: wrong action, expired event, mismatched bytes and oversized upload.

The source defaults allow up to 64 MiB per upload, with a 256 MiB absolute ceiling and configurable request limits. The actual server configuration should be read and tested before relying on those defaults. There is no throughput or concurrent-client benchmark from this review.

Shared bytes can have separate ownership claims

The shared NIP-96/Blossom store keys objects by SHA-256 and uses source-scoped ownership keys. Removing a Blossom claim does not silently remove a separate NIP-96 claim on the same object. This is a useful boundary when multiple protocol surfaces use the same stored bytes.

The store uses DETS for its metadata. The HTTP handler checks storage results before returning a successful upload response. Retention and failure recovery still depend on the configured metadata store, IPFS backend and their operating procedures. A CID is a byte reference, not an availability promise.

Deletion removes the relevant claim. Unpinning after removal of the last owner is separately controlled by blossom_unpin_on_delete and defaults to false. Even when enabled, unpinning is not a claim that all cached or mirrored copies have disappeared.

Connect it to a useful application record

A proposed workflow can attach an uploaded object's digest to a signed event and retain that association with a DamageBDD report or ECAI record. A consumer can then compare the retrieved file's hash with the expected value. The application must define which event or report authorises that association.

Upload authorization does not make later blob retrieval confidential. For private documents, establish encryption and access policy before using a publicly readable endpoint. ECAI's private index does not automatically ingest or protect a Blossom upload; it accepts prepared records through its own permissioned interface.

A first client pilot

Use a small public fixture with a locally computed digest. Exercise preflight, upload, HEAD, full download and a range request. Verify returned bytes, then repeat with bad authorization and mismatched content. Test two claimants on one object and confirm that deleting one claim leaves the other intact.

Restart the configured services and repeat retrieval. Record the client version, server revision, active limits, storage policy and exact outcomes. The result should be a repeatable client integration report, not simply one successful HTTP response.