Zero-knowledge file transfer — the relay is cryptographically blind.
End-to-end encrypted file sharing where the server never sees your key, your plaintext, or anything decryptable. If the relay is fully compromised (MOVEit-style SQLi / RCE / insider), the attacker gets nothing but unreadable ciphertext — by design, not by policy.
If this project's threat model matches your problem, a ⭐ star helps others find it.
Every other "secure" file-transfer tool asks you to trust the server — trust
its disk, its database, its logs, its admin. Poccer removes that trust entirely.
The relay stores and forwards only opaque ciphertext. The decryption key
travels in the URL #fragment, which browsers never transmit to the server per
the HTTP spec. Capture the relay, read its memory, dump its database — you get
noise. The security is structural, not a promise.
Proven, not promised. Most tools ask you to believe their server can't read your data. Poccer ships a continuous capture-relay test that fails the build if a single plaintext or key byte ever appears in data the relay processes — store, metadata, audit log, or API request. The zero-knowledge claim is a tested invariant, not a marketing line. (See the invariant →)
graph LR
S[Sender<br/>local machine] -- "AES-256-GCM encrypt<br/>CEK in URL #fragment" --> R{Relay<br/>public network<br/>blind to content}
R -- "ciphertext only" --> B[Recipient<br/>browser, Web Crypto]
S -. "key via link<br/>never through relay" .-> B
- Sender encrypts the file locally with AES-256-GCM → produces a Content Encryption Key (CEK).
- Relay stores/forwards only ciphertext — never plaintext, never the CEK.
- Recipient opens the link in a browser; the CEK arrives via the URL
#fragment, decryption happens locally with the Web Crypto API.
Critical invariant: the CEK exists only in the URL fragment and in the sender/recipient's memory. It is structurally impossible for the relay to read your file.
Prerequisites: Go 1.25+.
# 1. Build the two binaries
go build ./cmd/poccer-relay
go build ./cmd/poccer-send
# 2. Start a self-hosted relay (cryptographically blind)
./poccer-relay -addr :8080 -data ./poccer-data
# 3. In another terminal — send a file
./poccer-send ./secret.pdf http://localhost:8080The sender prints a link like:
http://localhost:8080/s/{share_id}#k={cek}
Open it in a browser (localhost or any HTTPS origin — Web Crypto requires a secure context). The browser decrypts the file locally and offers a download. The CEK never touches the relay.
# Wrap the CEK with a passphrase (Argon2id KDF) — key never in the link
./poccer-send -passphrase "correct horse" ./secret.pdf http://localhost:8080
# Live-passthrough mode (real-time stream, no at-rest storage)
./poccer-send -live -live-ctrl host:9000 -live-data host:9001 ./secret.pdf http://localhost:8080
# Run DLP + AV scanning on plaintext before encrypting (governance)
./poccer-send -dlp-pattern '\d{16}' -av-db badhashes.txt ./secret.pdf http://localhost:8080- Relay is cryptographically blind — stores/forwards only ciphertext; compromise yields nothing decryptable
- Key-in-fragment delivery — CEK travels in the URL
#fragment, never sent to the server per HTTP spec - Zero-install recipient — decrypts in any modern browser via Web Crypto API, no app or plugin
- Self-hostable relay — run your own blind relay in one command; no third-party trust required
- Passphrase mode — wrap the CEK with Argon2id so the key never appears in the link at all
- Live-passthrough streaming — real-time end-to-end transfer with no at-rest storage
- Expiration & download limits — time- and count-based access control on every share
- Immutable audit log — append-only event logging for compliance, without ever recording plaintext
- Client-side DLP / AV governance — scan plaintext before encryption so the relay stays zero-knowledge
Poccer is split into a cryptographically blind relay and thin sender / recipient edges that hold all the keys.
| Component | Package | Role |
|---|---|---|
| Relay server | cmd/poccer-relay, internal/relay |
Stores/forwards ciphertext only; enforces size & rate bounds |
| Sender | cmd/poccer-send, internal/sender |
Local encryption, optional DLP/AV pre-scan, upload |
| Crypto core | internal/crypto |
AES-256-GCM containers, Argon2id key wrapping |
| Browser recipient | internal/relay/web |
Web Crypto decrypt, zero install |
| Governance scan | internal/scan |
Client-side DLP (regex) + AV (hash DB) before encrypt |
| Capture relay test | internal/capture |
Proves plaintext/CEK never reach relay bytes |
The relay is intentionally stateless about content — it treats encrypted blobs as opaque byte ranges with enforced size limits. The live-passthrough mode reuses a tunnel kernel that is also key-blind.
A capture-relay test verifies that neither plaintext nor CEK ever appears in any byte the relay processes (store, metadata, audit log, API request). This is enforced as a continuous test invariant, not a one-time review.
- Store validation —
safeIDchecks (empty, path traversal, charset), 1 GiB PUT cap - API bounds — audit field size limits, 64 MiB replay cap
- Idempotency map — 4096-FIFO cap, key length ≤ 256
- Server timeouts — Read 30s / Write 5m / Idle 120s
- Sender validation — URL scheme check, server-returned ID charset validation
- Tunnel bounds — 1 GiB/transfer, 1024 conns, 30s handshake, 1h transfer deadline, single-use subscription, token auth
- Crypto hygiene —
UnwrapKeyverifies Argon2 output length before timing-sensitive operations - DLP / AV — pre-encrypt plaintext scan (credit card Luhn / SSN / AWS key / PEM private key + custom regex + SHA256 malicious hash comparison)
Relay compromise (SQLi, RCE, insider) → attacker obtains only ciphertext. Without the CEK — which only sender and recipient possess — the data is unreadable. This is structural: there is no privileged relay path to plaintext.
Runnable now (α-2.2): store-and-forward, link-fragment & passphrase key delivery, browser recipient, self-hosted relay, expiration / download limits, immutable audit log, idempotent uploads, multi-chunk resumable upload, client-side DLP/AV scanning, background expired-blob sweeper, live data-channel token auth.
Tested, partially wired to CLI: live-passthrough mode (-live flag works;
live control-channel policy is α-2.x).
Roadmap: Preview (recipient browser rendering); enterprise tier — SSO, SIEM export, legal hold, client-side watermarking; ClamAV integration (heuristic AV).
go test ./...The suite includes the capture-relay invariant test that fails if any plaintext or CEK byte reaches relay-processed data.
For the full design spec, see Poccer ZK Secure Transfer Design.
PRs welcome. This is an active alpha — open an issue first to discuss scope. Security findings: please open a private security advisory rather than a public issue.
Licensed under the Apache License, Version 2.0.
Poccer chose Apache-2.0 (over MIT) deliberately: the patent grant matters for cryptography and enterprise adoption. You may use, modify, distribute, and host commercially under the terms of the license.