lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

README.md (8579B)


      1 # radroots_blossom
      2 
      3 `radroots_blossom` provides portable Blossom protocol primitives for Radroots:
      4 canonical SHA-256 values and root hash paths, blob URLs, media types, BUD-02
      5 descriptors, byte-verification typestates, and pure BUD-11 authorization
      6 claims.
      7 
      8 The crate supports `no_std` environments with `alloc`. It performs no I/O,
      9 starts no tasks or threads, reads no clocks or process state, and owns no HTTP
     10 client, upload scheduler, cache, filesystem, credential, signer, or global
     11 authentication state.
     12 
     13 ## Example
     14 
     15 Parse a BUD-02 descriptor, apply the Radroots reference policy, and prove that
     16 its hash, size, and media type match locally available bytes:
     17 
     18 ```rust
     19 use radroots_blossom::{BlobDescriptor, BlobUrl, MediaType, Sha256};
     20 
     21 let bytes = b"hello";
     22 let hash = Sha256::digest(bytes);
     23 let media_type = MediaType::parse("text/plain")?;
     24 let url = BlobUrl::parse(&format!("https://media.example/{hash}.txt"))?;
     25 let descriptor = BlobDescriptor::new(
     26     url,
     27     hash,
     28     bytes.len() as u64,
     29     media_type.clone(),
     30     1_725_105_921,
     31 )?;
     32 
     33 let verified = descriptor
     34     .approve_reference()?
     35     .verify_bytes(bytes, &media_type)?;
     36 
     37 assert_eq!(verified.sha256(), hash);
     38 assert_eq!(verified.size(), 5);
     39 assert_eq!(verified.url().as_str(), format!("https://media.example/{hash}.txt"));
     40 # Ok::<(), radroots_blossom::Error>(())
     41 ```
     42 
     43 The same program is available as the
     44 [`verified_descriptor`](examples/verified_descriptor.rs) example.
     45 
     46 ## Public API
     47 
     48 The crate root intentionally exports `AuthorizationClaim`, `BlobDescriptor`,
     49 `BlobUrl`, `ByteVerifiedDescriptor`, `MediaType`, `Sha256`, and the aggregate
     50 [`Error`](https://docs.rs/radroots_blossom/latest/radroots_blossom/enum.Error.html).
     51 Supporting states and constructors remain in these modules:
     52 
     53 - `authorization` — bounded BUD-11 claim parsing, endpoint-scope validation,
     54   and upload-claim wire parts;
     55 - `descriptor` — BUD-02 descriptors and the approved-reference,
     56   byte-commitment, and byte-verified states;
     57 - `hash` — SHA-256 values, safe file extensions, and root hash paths;
     58 - `media_type` — parsed and deterministically canonicalized media types;
     59 - `url` — structural blob URLs and the stricter approved-reference state.
     60 
     61 The normative responsibility and dependency boundary are defined by the
     62 [`radroots_blossom` package charter](../../contracts/crates/release_v1/radroots_crates_release_v1.toml).
     63 The reviewed pre-release surface is recorded in the
     64 [`radroots_blossom` API baseline](../../contracts/api_baselines/radroots_blossom.txt).
     65 
     66 ## Features
     67 
     68 | Feature | Default | Effect |
     69 | --- | --- | --- |
     70 | `std` | yes | Implements the standard error integration and enables standard-library support in dependencies; protocol behavior remains portable. |
     71 | `serde` | yes | Implements checked string serialization for hashes, paths, URLs, and media types, plus checked BUD-02 descriptor serialization. |
     72 
     73 Disabling default features leaves the `no_std` + `alloc` protocol model.
     74 Features are additive; neither feature selects a runtime, transport, backend,
     75 clock, signer, credential source, or side effect.
     76 
     77 ## Protocol and validation boundaries
     78 
     79 Protocol behavior is pinned to Blossom commit
     80 `b5bd2801d1763aa635fc8fea7a76597e0eb18990`:
     81 
     82 - [BUD-01](https://github.com/hzrd149/blossom/blob/b5bd2801d1763aa635fc8fea7a76597e0eb18990/buds/01.md)
     83   defines root hash paths and basic blob retrieval;
     84 - [BUD-02](https://github.com/hzrd149/blossom/blob/b5bd2801d1763aa635fc8fea7a76597e0eb18990/buds/02.md)
     85   defines blob descriptors;
     86 - [BUD-11](https://github.com/hzrd149/blossom/blob/b5bd2801d1763aa635fc8fea7a76597e0eb18990/buds/11.md)
     87   defines Nostr authorization claims.
     88 
     89 `Sha256`, `HashPath`, `BlobUrl`, and `MediaType` reject ambiguous encodings and
     90 emit their documented canonical textual forms. A `BlobDescriptor` additionally
     91 requires a URL file extension and the same hash in its URL and `sha256` field.
     92 These checks establish structural protocol validity; they do not make a remote
     93 reference trustworthy.
     94 
     95 `BlobUrl::parse` accepts structurally valid public HTTP references so received
     96 Blossom data can be represented faithfully. `BlobUrl::approve` advances only
     97 HTTPS or loopback HTTP references to `ApprovedBlobUrl`. Callers must not fetch,
     98 display, cache, or otherwise act on an unapproved URL. URL approval is a narrow
     99 transport policy, not host reputation, content safety, malware scanning, or
    100 application media policy.
    101 
    102 `BlobUrl::upload_url` projects the BUD-02 `/upload` URL at the same scheme,
    103 host and port. It preserves the canonical blob reference used for retrieval
    104 verification and grants no transport authority. Upload callers must still
    105 enforce their configured endpoint policy and bind authorization to exact bytes.
    106 
    107 `ByteVerifiedDescriptor` can only be produced after an approved descriptor's
    108 hash, byte length, and approved media type match supplied bytes or a locally
    109 computed `ByteCommitment`. It proves local descriptor-to-byte agreement. It is
    110 not a server receipt, upload acknowledgement, authenticity proof, or safe-media
    111 classification.
    112 
    113 ## Authorization and security
    114 
    115 `AuthorizationClaim` parses the BUD-11 content and tags needed for endpoint
    116 authorization. Validation checks caller-supplied current time, action, server,
    117 hash, expiration, creation age, and lifetime policy. The crate never reads a
    118 clock and never verifies a Nostr event signature or signer identity. The
    119 composing Nostr layer must validate event kind `24242`, signature, author,
    120 request association, and canonical `Authorization: Nostr` encoding before an
    121 endpoint treats a validated claim as authenticated. Kind `24242` is ephemeral
    122 HTTP authorization material and must not be published to relays.
    123 
    124 `AuthoredUploadClaim` emits checked event wire parts; it does not sign them or
    125 send a request. Authorization content is bounded to 4,096 bytes, server domains
    126 use lowercase ASCII DNS, canonical IPv4, or bracketed canonical IPv6 forms,
    127 timestamps are explicit
    128 caller inputs, and authored lifetimes are limited to 300 seconds.
    129 
    130 The crate forbids unsafe Rust. It does not provide confidentiality,
    131 authentication, authorization storage, credential redaction, content scanning,
    132 SSRF protection beyond its explicit URL approval rule, or resource limits for
    133 the bytes callers choose to hash. Hosts must bound untrusted payload sizes
    134 before hashing or retaining them and must enforce application policy at their
    135 own trust boundaries.
    136 
    137 ## Serialization
    138 
    139 With `serde`, SHA-256 values are lowercase hexadecimal strings; file extensions,
    140 hash paths, blob URLs, and media types use their canonical string forms; and
    141 BUD-02 descriptors use the protocol fields `url`, `sha256`, `size`, `type`, and
    142 `uploaded`. Deserialization re-runs the same parsers and descriptor constructor,
    143 so malformed or cross-field-inconsistent values cannot enter through the
    144 supported serde surface.
    145 
    146 Authorization states and approved or byte-verified typestates intentionally do
    147 not implement serde. Reconstruct them by parsing untrusted wire parts and
    148 reapplying the current request, time, URL, and byte-verification policies.
    149 Serialization alone never preserves an approval or authentication decision.
    150 
    151 ## Execution and commit semantics
    152 
    153 Operations are synchronous and deterministic. Hashing cost is linear in the
    154 caller-supplied byte slice; parsing and authored authorization construction may
    155 allocate in proportion to bounded input. There are no asynchronous cancellation
    156 points, deadlines, retries, callbacks, network requests, partial external
    157 effects, or durable commit points. A successful call returns its complete
    158 in-memory value; an error returns without durable mutation because the crate
    159 owns no external state.
    160 
    161 HTTP-capable callers must define their own cancellation and commit boundary.
    162 In particular, local byte verification does not authorize marking a BUD-02
    163 upload complete: durable upload success may be committed only after the
    164 composing transport has validated its successful server response.
    165 
    166 ## Intended consumers
    167 
    168 `radroots_blossom` is intended directly for `radroots_event`,
    169 `radroots_event_codec`, `radroots_nostr`, and media clients that need portable
    170 Blossom values. Applications should normally begin with the curated `radroots`
    171 crate or the advanced `radroots_sdk` composition surface, where transport,
    172 signing, storage, and application media policy can be supplied explicitly.
    173 
    174 The package is pre-1.0. Its durable responsibility and package identity are
    175 fixed, while API-breaking changes follow the workspace's pre-1.0 versioning
    176 policy.
    177 
    178 ## License
    179 
    180 Licensed under either Apache-2.0 or MIT, at your option.