$ plaintxt --security

security

what we built, what it protects against, and where the limits are. no marketing, just facts.


// encryption model

key exchange: ECDH P-256

key derivation: HKDF-SHA-256

message encryption: AES-256-GCM

key generation: browser WebCrypto API (non-extractable private key)

private key storage: IndexedDB, device-local only

per-message keys: fresh ephemeral key pair each message (not a ratchet — see limitations)

each message uses a fresh ephemeral sender key pair, so no single key opens every message. this is not full forward secrecy: the ephemeral key is agreed against your long-term identity key, so an attacker who obtains that key and has the stored ciphertext can still read past messages. deleting is what actually removes them.

// what we protect against

✓
server breach
the server stores only ciphertext. a full database dump reveals no message content.
✓
network interception
messages are encrypted before transmission. TLS provides an outer layer, E2EE is the inner layer.
✓
passive surveillance
no plaintext ever passes through our infrastructure. there is nothing to log.
✓
identity linkage
no email, phone, or real name is required. identities are username + public key only.
✓
deletion is real
deleting a message, conversation, or identity is a hard delete — no soft delete, no archive, no backup we could restore from.
✓
identity accumulation
burning an identity erases everything tied to it and releases the username. unused free identities are deleted after 180 days.

// honest limitations

we document what plaintxt does not protect against. security claims that omit limitations are marketing, not engineering.

!
endpoint compromise
if your device or browser is compromised, an attacker with local access can read plaintext messages on-screen or extract keys from IndexedDB. E2EE does not protect against this.
!
recipient behavior
once the recipient decrypts a message, they can screenshot, copy, or forward it. deleting removes server-side access — it cannot pull back what a person already saw.
!
retained history raises the stakes on your key
messages are kept until you delete them, so an attacker who obtains your device key can read the history that is still on the server. this used to be limited by everything expiring in 24 hours. it is no longer. delete what you do not need, and burn an identity you are finished with.
!
not Double Ratchet
plaintxt derives a fresh key per message from an ephemeral key pair, but it is not the Signal Double Ratchet: there is no ratchet step and compromise of your long-term identity key exposes past messages an attacker can still obtain. we don't claim otherwise.
!
no key verification yet
we hand you the other person's public key. there is no fingerprint or safety-number check, so a compromised server could in principle substitute a key. verification is the top item on the security roadmap.
!
your identity is permanent, your browser storage is not
the server keeps your identity indefinitely, but the private key that opens it lives in this browser's IndexedDB — which can be evicted under storage pressure, and is wiped by clearing site data or closing a private window. lose the key and the account is unreachable even though it still exists. Power users can export an encrypted identity bundle; Pro and Power should also save a recovery code.
!
metadata
we store timestamps and username pairs for conversation routing. we do not store message content, but we do know that two usernames communicated at a given time.

// infrastructure

API: Cloudflare Workers — edge-deployed, no persistent application servers

database: Cloudflare D1 — stores ciphertext, timestamps, public keys only

attachments: Cloudflare R2 — encrypted client-side, removed when you delete them

WebSocket: Cloudflare Durable Objects — stateless relay, no message storage

CDN: Cloudflare Pages — static assets only, no server-side rendering of private data

// responsible disclosure

found a vulnerability? contact us at plaintxt.app/contact. we respond to all credible security reports. we do not have a bug bounty program at this stage, but we take every report seriously and will credit researchers who help us improve.