FireCloud
Private, encrypted, distributed storage across machines you own.
Files are chunked and encrypted on the client before anything touches the network, so storage nodes only ever hold ciphertext. With five or more nodes a file is erasure coded and survives losing a third of the cluster. S3 means renting someone else's disks, Syncthing has no erasure coding, and IPFS announces content on a public DHT. FireCloud is for a LAN of machines you already run yourself.
Install
pip install git+https://github.com/rajashekharsunkara/firecloud.git
# optional extras
pip install "firecloud-devnet[rag]" # local RAG pipeline
pip install "firecloud-devnet[mlops]" # ML artifact store
Quickstart with containers
Works with podman (rootless is fine) or docker; swap the command name.
git clone https://github.com/rajashekharsunkara/firecloud.git
cd firecloud
cp .env.example .env # set FIRECLOUD_PASSPHRASE in .env
# create the network keystore the containers share
podman build -t firecloud .
mkdir -p test_config/.firecloud
podman run --rm --env-file .env \
-v "$PWD/test_config/.firecloud:/root/.firecloud:z" firecloud init
# bootstrap node + 3 storage nodes
podman compose build
podman compose up -d
Note for podman: podman compose up reuses service images if they already
exist, so run podman compose build after pulling changes.
Upload from one node, download from another:
podman exec firecloud-bootstrap sh -c 'echo "hello cluster" > /data/hello.txt'
podman exec firecloud-bootstrap firecloud upload /data/hello.txt \
--bootstrap 127.0.0.1:7474 --storage /tmp/cli
podman exec firecloud-node-1 firecloud download <file_id> /tmp/hello.txt \
--bootstrap 127.0.0.1:7475 --storage /tmp/cli
podman exec firecloud-bootstrap firecloud verify \
--bootstrap 127.0.0.1:7474 --storage /tmp/cli
--storage /tmp/cli gives the one-shot command its own scratch directory so
it doesn't share state with the daemon in the same container. Stop a
container (podman stop firecloud-node-3) and the download still works;
verify reports the file as degraded until the node returns.
Run it on real machines
Install the package on each machine. The network key is the network: nodes holding the same key can talk, everyone else fails the handshake.
# machine A
firecloud init # writes ~/.firecloud/network.key
firecloud start --port 7474
# every other machine: copy the key over first
scp userA@machine-a:~/.firecloud/network.key ~/.firecloud/
firecloud start --port 7474 --bootstrap <machine-a-ip>:7474
One --bootstrap peer is enough; a joining node asks it for the rest of the
cluster, connects to them, and pulls the file catalog. Nodes listen on all
interfaces, so the only thing to check is the firewall on each machine
(sudo firewall-cmd --add-port=7474/tcp on Fedora, sudo ufw allow 7474/tcp
on Ubuntu).
Then from any machine on the network:
firecloud upload ./photos.zip --bootstrap <machine-a-ip>:7474
firecloud list --bootstrap <machine-a-ip>:7474
firecloud download <file_id> ./out --bootstrap <machine-a-ip>:7474
firecloud verify --bootstrap <machine-a-ip>:7474
To try multiple nodes on a single machine, give each its own port and storage directory:
export FIRECLOUD_PASSPHRASE=test-pass
firecloud init
firecloud start --port 7474 --storage /tmp/fc/n0 &
for i in 1 2 3 4; do
firecloud start --port $((7474 + i)) --storage /tmp/fc/n$i \
--bootstrap 127.0.0.1:7474 &
done
CLI reference
firecloud init # create a network keystore
firecloud start # run a node
firecloud upload <path> # chunk, encrypt, distribute
firecloud download <id> <out> # retrieve, verify, reassemble
firecloud verify [<id>] # healthy / degraded / unrecoverable
firecloud list # file catalog across the network
firecloud sync <folder> # two-way folder sync
firecloud status / peers / delete <id>
Environment variables, all optional: FIRECLOUD_PASSPHRASE (skip the
prompt), FIRECLOUD_DATA_DIR (storage directory), FIRECLOUD_MAX_STORAGE_GB
(chunk store quota), FIRECLOUD_BOOTSTRAP (comma-separated peers to join on
start), FC_RAG_MODEL (Ollama model for the RAG layer).
Architecture
┌─────────────────────────────────────────┐
│ fc-rag (private RAG, opt-in) │
│ fc-mlops (artifact store, opt-in) │
│ containers + GitHub Actions CI │
│ core: storage, crypto, P2P transport │
└─────────────────────────────────────────┘
The core does XChaCha20-Poly1305 chunk encryption, FastCDC content-defined chunking, zfec erasure coding, and mDNS peer discovery. Manifests use Lamport timestamps with last-writer-wins merges. Nodes talk a small binary RPC protocol over TLS.
fc-mlops stores version-tracked ML artifacts through the Node API and
ships a FastAPI telemetry endpoint with IsolationForest anomaly detection.
fc-rag indexes documents with fastembed, searches them in an embedded
Qdrant, and generates answers with a local Ollama model.
Security
Chunk IDs are HMAC-SHA-256 under a key derived from the network key rather than a plain content hash. Someone who suspects you store a particular file can't confirm it by hashing the plaintext themselves, because valid chunk addresses require the network key.
Chunks are encrypted before they leave the client, so storage nodes hold authenticated ciphertext only. The transport caps frame sizes, times out handshakes and requests, and compares auth tokens in constant time.
Devnet limitations to know about: node TLS certificates are self-signed and clients skip verification, so the TLS layer stops passive snooping but not an active man-in-the-middle on your LAN. The chunk payloads stay end-to-end encrypted either way. Run this on networks you control.
Private RAG (fc-rag)
Index documents and ask questions against a local model. Embeddings (fastembed), vector search (embedded Qdrant), and generation (Ollama) all run on your machine.
pip install "firecloud-devnet[rag]"
ollama pull llama3.2:3b # any local model; set FC_RAG_MODEL to change
fc-rag index ./docs
fc-rag query "How does FireCloud handle node departure?"
If Ollama isn't running, the query still prints the retrieved passages and sources; only the generated answer is skipped.
MLOps artifact store (fc-ml)
pip install "firecloud-devnet[mlops]"
fc-ml save ./model.pt --name resnet --version 1.0.0 --type model --metric accuracy=0.94
fc-ml simulate-failure
Development
git clone https://github.com/rajashekharsunkara/firecloud.git
cd firecloud
pip install -e ".[dev]"
pytest tests/ -v
ruff check firecloud fc_rag fc_mlops
License
MIT, see LICENSE.
Metadata
Release files for firecloud-devnet 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| firecloud_devnet-0.2.1.tar.gz | 70.4 kB | With provenance | Details for firecloud_devnet-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| firecloud_devnet-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for firecloud_devnet-0.2.1-py3-none-any.whl |
Total release size: 126.5 kB
Release files / firecloud_devnet-0.2.1.tar.gz
| Download URL | firecloud_devnet-0.2.1.tar.gz |
|---|---|
| Size | 70.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bf640f5364847654c3ddd16954f6099377cccd8b791c2560d74142726235e82e
|
|
BLAKE2b-256 checksum How to use checksums |
29314a0ec04f57a83079e223e36cda6d3c77f92835fcabc58f452e351a98701e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 3, 2026.
Transparency logRelease files / firecloud_devnet-0.2.1-py3-none-any.whl
| Download URL | firecloud_devnet-0.2.1-py3-none-any.whl |
|---|---|
| Size | 56.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7d9ac2af6c11db8529867a84d497defe8d40c25fa56e9d44f276e0783d98ad34
|
|
BLAKE2b-256 checksum How to use checksums |
97605ddb54f22c674b56d52ce0b8c7be99006d301f919c58b1614b73da4f8077
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 3, 2026.
Transparency logSecurity for firecloud-devnet 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for firecloud_devnet-0.2.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.