Core principle
The relay is an untrusted intermediary. It stores only ciphertext and has no access to keys or plaintext. A fully compromised relay cannot read, forge, or retroactively recover any transfer. This is not a policy — it is a cryptographic guarantee.
The guarantee above applies to transfers from the official SDKs (sdk-py 3.0.0, sdk-js 3.0.0), the WebApp tools (ParaShare, ParaDrop), and the anonymous /send link flow — every one of those encrypts in the client before bytes leave the device. The Chromium and Outlook extensions currently take a server-side encryption path while their client-side crypto is being finished; until that migration lands, treat extension uploads as relay-side, not zero-knowledge. Per-client status: crypto-agility § 06.
For the full audit history, patch timeline, and cryptographic architecture, see the architecture page.
Cryptography
All algorithms are from NIST post-quantum standards (FIPS 203, 204, 205, 206) or established symmetric primitives. Nothing custom. No proprietary key exchange. The relay loads 3 KEMs and 18 signatures; clients choose, the relay validates, and the live registry is at /v2/capabilities. See crypto agility for the wire format and full algorithm table.
| Algorithm | Role | Standard |
|---|---|---|
| ML-KEM-768 | Key encapsulation — post-quantum KEM | NIST FIPS 203 |
| ECDH P-256 | Classical key exchange (hybrid) | NIST SP 800-56A |
| HKDF-SHA256 | Key derivation from shared secrets | RFC 5869 |
| AES-256-GCM | Symmetric encryption + authentication | NIST SP 800-38D |
| ML-DSA-65 | Digital signatures — relay identity | NIST FIPS 204 |
| Argon2id | Password-based blob encryption | RFC 9106 |
| SHA3-256 | CT log Merkle hashing | NIST FIPS 202 |
Hybrid key exchange
ParaShare authenticated transfers use ML-KEM-768 and ECDH P-256 simultaneously. The shared secret is the concatenation of both — breaking one provides no advantage. This protects against store-now-decrypt-later attacks while maintaining compatibility with classical infrastructure. Anonymous /send transfers use AES-256-GCM with a browser-generated key delivered in the URL fragment.
See also: Harvest Now, Decrypt Later → — why data collected today can be decrypted at Q-Day, and how RAM-only transfer removes the target.
Pre-shared secret (PSS)
An optional out-of-band password added to HKDF input. Even a fully compromised relay cannot decrypt PSS-protected transfers — the relay would need to serve the correct ciphertext and know the PSS. Recommended for healthcare and legal workflows.
Relay architecture
Encrypted blobs are stored in process memory, never written to disk. A relay restart destroys all blobs. No database, no filesystem writes.
Each blob is destroyed after the first successful download. Memory is zeroed immediately. There is no second chance to retrieve it.
ParaShare authenticated uploads are padded to a fixed 5 MB block for DPI masking. Anonymous uploads are stored at their actual encrypted size, up to a 5 MB maximum.
Each relay generates a post-quantum signing keypair on first boot. Registrations are signed and logged in the CT chain — verified_since proves continuous identity.
What a compromised relay cannot do
Authentication
Paramant has no passwords. Humans authenticate with email and a time-based code from an authenticator app. Machines authenticate with long-lived API keys. What we do not have, we cannot leak.
Sign in at paramant.app or through a browser extension with your email address and the current 6-digit code from your authenticator app. Sessions last one hour. TOTP verification uses SHA-256 HMAC, matching the cryptographic posture of the transport layer. Compatible authenticator apps are listed at /help/authenticator-apps.
Scripts, SDK calls, SCADA integrations, and IoT devices authenticate with an API key in the X-Api-Key HTTP header. No TOTP, no sessions, no human interaction required. Suitable for headless automation.
No passwords. No password hashes. No security questions. No password reset tokens. Our database cannot leak a password because our database does not have the concept of one.
After TOTP verification, a 256-bit session token is issued as an httpOnly Secure SameSite=Strict cookie. The token lives in Redis with a one-hour sliding expiry. API keys never touch the browser.
Rate limiting and replay protection
TOTP codes expire thirty seconds after issue. Each code can be used exactly once across the system, enforced atomically in Redis. Login attempts are rate-limited to five per IP per fifteen minutes and ten per email per fifteen minutes. After ten consecutive failures, an account locks for thirty minutes.
Compared to alternatives
Most encrypted file transfer services use password authentication with optional two-factor as an upgrade. Paramant reverses this. TOTP is required for human access from day one. The surface for credential theft is close to zero because there is nothing to phish, stuff, or reset.
Setting up your authenticator → When to use API key vs TOTP → Backup codes →
Four-layer key verification
The relay distributes public keys. An attacker who controls the relay could serve wrong keys. These four layers prevent that:
| Layer | Mechanism | Protects against |
|---|---|---|
| 1 — TOFU | First-use fingerprint stored locally. Every subsequent fetch must match. | Key swap after first contact |
| 2 — Out-of-band | Both parties compute the same SHA-256 fingerprint and compare via phone/Signal/QR. | Relay MITM on first contact |
| 3 — PSS | Pre-shared secret mixed into HKDF. Wrong key = undecryptable ciphertext. | Relay MITM at any time |
| 4 — CT log + ML-DSA-65 | Key registrations are signed and logged in Merkle chain. Retroactive injection is impossible. | Key injection, timestamp fraud |
Jurisdiction & privacy
| Server location | Hetzner Nuremberg, Germany |
| Legal jurisdiction | EU / Germany (GDPR) |
| US CLOUD Act | Not applicable — no US infrastructure, no US company |
| Data retained | No plaintext, no keys. Only: transfer hash, creation timestamp, approximate encrypted size (up to 5 MB; exact 5 MB for ParaShare), view count. Deleted on burn. |
| IP logging | Nginx access logs. Not linked to transfer content. Retention: 7 days. |
| Analytics | None. No third-party scripts on the relay or API. |
Responsible disclosure
Report to privacy@paramant.app — encrypted with our PGP key if the details are sensitive. Do not open a public GitHub issue before coordinating.
PGP key fingerprint — verify before encrypting:09AA 452A 69DE F4A4 EB4B 72DC 5A34 D82F DAF3 54CD
What we ask
Do not publicly disclose before we have had a reasonable chance to fix. Do not access or modify data that does not belong to you. Do not run automated scans at volume that impacts service availability. Report to us first, not to third parties.
Scope
In scope: paramant.app, *.paramant.app, browser extensions published by us, API endpoints at docs/api.
Out of scope: social engineering, physical attacks, denial of service, third-party services (Resend, Hetzner, Cloudflare).
Rewards
No monetary bounty at this time. Credit on our acknowledgements page, and priority access to new features.
ParamantOS
The official installer image for self-hosted relay deployments. Hardened NixOS with the relay pre-installed.
| Component | Configuration |
|---|---|
| SSH KEX | mlkem768x25519-sha256 + curve25519 — ML-KEM FIPS 203 |
| SSH host key | Ed25519 only — no RSA, no ECDSA |
| SSH auth | Public key only — no passwords, no GSSAPI, no forwarding |
| Kernel | unprivileged_bpf_disabled=1, kptr_restrict=2, bpf_jit_harden=2 |
| Firewall | Ports 22 + 3000–3004 only |
| Service isolation | Dedicated system user, systemd NoNewPrivileges, ProtectSystem=strict |
| CVEs mitigated | CVE-2023-51767, CVE-2025-26465, CVE-2025-26466, CVE-2025-32728 |