build 2.5.0 · aes-256-gcm / post-quantum · eu/de · ram only
DEFENSE IN DEPTH

Security

We treat security as infrastructure, not a feature. Every component is designed assuming the relay is compromised. This page documents how, what was audited, and how to report issues.

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.

Where the zero-knowledge guarantee holds today

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.

AlgorithmRoleStandard
ML-KEM-768Key encapsulation — post-quantum KEMNIST FIPS 203
ECDH P-256Classical key exchange (hybrid)NIST SP 800-56A
HKDF-SHA256Key derivation from shared secretsRFC 5869
AES-256-GCMSymmetric encryption + authenticationNIST SP 800-38D
ML-DSA-65Digital signatures — relay identityNIST FIPS 204
Argon2idPassword-based blob encryptionRFC 9106
SHA3-256CT log Merkle hashingNIST 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

RAM-only storage

Encrypted blobs are stored in process memory, never written to disk. A relay restart destroys all blobs. No database, no filesystem writes.

Burn-on-read

Each blob is destroyed after the first successful download. Memory is zeroed immediately. There is no second chance to retrieve it.

5 MB padding

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.

ML-DSA-65 relay identity

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

Read file contents — relay holds only ciphertext, never keys
Substitute a registered public key (after TOFU or PSS is used)
Decrypt any stored ciphertext — no key access
Identify ParaShare transfer size — authenticated transfers look identical (fixed 5 MB padding)
Recover burned blobs — memory is zeroed immediately on download
Forge CT log entries — Merkle chain is append-only and tamper-evident
Break ML-KEM-768 — NIST FIPS 203, post-quantum secure


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.

For humans

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.

For machines

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.

What we do not store

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.

Session security

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:

LayerMechanismProtects 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 locationHetzner Nuremberg, Germany
Legal jurisdictionEU / Germany (GDPR)
US CLOUD ActNot applicable — no US infrastructure, no US company
Data retainedNo 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 loggingNginx access logs. Not linked to transfer content. Retention: 7 days.
AnalyticsNone. 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

AcknowledgementWithin 48 hours
Initial assessmentWithin 5 working days
Status updatesEvery 7 days until resolved
Disclosure window90 days (coordinated)
CreditAcknowledgements page (with permission)
Safe harborNo legal action against good-faith researchers

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.

ComponentConfiguration
SSH KEXmlkem768x25519-sha256 + curve25519 — ML-KEM FIPS 203
SSH host keyEd25519 only — no RSA, no ECDSA
SSH authPublic key only — no passwords, no GSSAPI, no forwarding
Kernelunprivileged_bpf_disabled=1, kptr_restrict=2, bpf_jit_harden=2
FirewallPorts 22 + 3000–3004 only
Service isolationDedicated system user, systemd NoNewPrivileges, ProtectSystem=strict
CVEs mitigatedCVE-2023-51767, CVE-2025-26465, CVE-2025-26466, CVE-2025-32728

ParamantOS on GitHub →