Store Files¶
This guide covers uploading, downloading, and deleting encrypted files (blobs).
How blob encryption works¶
Every blob is encrypted with a randomly-generated data encryption key (DEK). The DEK is returned to you when you upload and must be stored alongside the blob ID — the server never has it.
This is different from message and state encryption, where keys are derived from symmetric_root. Blob DEKs are ephemeral per-blob keys; you are responsible for storing them.
Uploading a file¶
from reeeductio import Space
space = Space(
space_id='S...',
member_id='U...',
private_key=...,
symmetric_root=...,
base_url='http://localhost:8000',
)
with open('report.pdf', 'rb') as f:
data = f.read()
result = space.encrypt_and_upload_blob(data)
print('Blob ID:', result.blob_id) # B...
print('DEK (hex):', result.dek.hex()) # save this!
import { Space } from 'reeeductio';
const space = new Space({ spaceId, keyPair, symmetricRoot, baseUrl: 'http://localhost:8000' });
const data = new Uint8Array(await file.arrayBuffer());
const result = await space.encryptAndUploadBlob(data);
console.log('Blob ID:', result.blob_id); // B...
console.log('DEK (hex):', Buffer.from(result.key).toString('hex')); // save this!
Save your DEK
Without the DEK you cannot decrypt the blob. Store it somewhere safe alongside the blob ID — for example, encrypted inside a message or in the space's State.
Downloading and decrypting¶
Storing the DEK alongside the blob ID¶
The most common pattern is to post both the blob ID and the DEK as an encrypted message, so other authorized members can retrieve it:
import json
result = space.encrypt_and_upload_blob(data)
# Store blob ID + DEK as an encrypted message
payload = json.dumps({
'blob_id': result.blob_id,
'dek': result.dek.hex(),
'filename': 'report.pdf',
'content_type': 'application/pdf',
}).encode()
space.post_encrypted_message('files', 'file.upload', payload)
const result = await space.encryptAndUploadBlob(data);
const payload = JSON.stringify({
blob_id: result.blob_id,
dek: Buffer.from(result.key).toString('hex'),
filename: 'report.pdf',
content_type: 'application/pdf',
});
await space.postEncryptedMessage('files', 'file.upload', stringToBytes(payload));
Recipients read the message, extract the blob ID and DEK, then download and decrypt:
const { messages } = await space.getMessages('files');
for (const msg of messages) {
const meta = JSON.parse(bytesToString(space.decryptMessageData(msg, 'files')));
const blob = await space.downloadAndDecryptBlob(
meta.blob_id,
Uint8Array.from(Buffer.from(meta.dek, 'hex')),
);
// blob is a Uint8Array of the file bytes
}
Deleting a blob¶
Deletion is permanent
Once a blob is deleted, it cannot be recovered. Any messages containing the blob ID will have a broken reference.
Uploading without encryption¶
If you need to store files that don't need to be encrypted (e.g. publicly readable assets), use the plaintext upload:
Related¶
- Blobs — concept overview
- Send Messages — posting blob IDs as messages
- Topics & Messages