How Grove works
Grove separates immutable blob bytes from the public keys that claim an ownership reference to those bytes.
Upload path
client
-> signs a short-lived kind 24242 upload authorization
-> streams bytes to PUT /upload
Grove
-> validates authorization and expected hash
-> streams into a temporary file while hashing and counting
-> rejects mismatched or oversized content
-> atomically moves valid bytes into content-addressed storage
-> records blob metadata and uploader ownership in SQLite
The upload is never trusted merely because the client supplied a digest. Grove computes SHA-256 over the body it actually received.
Filesystem and metadata
Blob bytes are stored under a two-character hash prefix:
data/
├── grove.db
├── blobs/
│ └── ab/
│ └── abcdef...<64-character-sha256>
└── tmp/
SQLite records the blob's digest, size, media type, upload time, and its owner references. Foreign keys and WAL mode are enabled.
Deduplication and ownership
The same exact ciphertext has the same SHA-256 digest. When two public keys upload identical bytes, Grove keeps one physical file and records two owner references.
Deleting a blob is therefore owner scoped:
- the caller must sign a
deleteauthorization for that hash; - Grove removes only that caller's ownership reference; and
- the physical bytes are removed only when no owner references remain.
This is storage accounting, not legal ownership or access control over retrieval. Blob retrieval is public to anyone who knows the hash.
Retrieval
GET /<sha256> and HEAD /<sha256> return the stored bytes and metadata. An
optional filename extension is accepted for client convenience but does not
participate in addressing. Byte ranges are supported by the underlying file
response, which is useful for PDFs, audio, video, and resumable retrieval.
Successful retrievals are marked immutable because a digest path cannot
legitimately change to different bytes. Error and administrative responses use
Cache-Control: no-store.
What Grove deliberately leaves outside
Grove does not decrypt, transform, scan, classify, index, or interpret blob contents. It does not hold user signing keys. TLS termination, request-rate controls, network filtering, monitoring, backups, and multi-site replication remain deployment responsibilities.