You don't have to trust us
A standard for web apps that encrypt your data in the browser before it reaches a server. You don't take the developer's word for it — you verify it yourself.
The idea
Most apps ask you to trust that they handle your data responsibly. Credible Encryption is different: your data is encrypted before it leaves your browser, using a key that only you have. The server never sees plaintext. This isn't a privacy policy — it's a verifiable property of the code.
No one can read your data. Not the developer. Not a hacker who breaches the server. Not the hosting provider. Not Amazon Web Services. Not even the NSA — AES-256 has no known cryptographic weakness, and brute-forcing a 256-bit key would take longer than the age of the universe.
Any app that adopts this standard derives an encryption key from your password using PBKDF2 (100,000+ iterations, SHA-256) and encrypts sensitive fields with AES-256-GCM client-side. The key stays in your browser. The server stores ciphertext it cannot read.
What qualifies
An app meets the Credible Encryption standard when:
- All sensitive user content is encrypted in the browser before any network request
- The encryption key is derived from the user's password and never transmitted
- The server only stores and returns ciphertext — it cannot decrypt user content
- Anyone can verify this by inspecting network requests in DevTools
Standard parameters
Every CE app uses the same encryption, so verification is universal — not per-app.
Because the parameters are fixed, a single verification tool works for every CE app. Apps integrate using a small open-source library — ce.encrypt(plaintext) — which handles both the encryption and the communication with the verification extension.
What's typically encrypted vs. visible
Encrypted (unreadable to server)
- User-created content (names, text, entries)
- Relationships and labels between items
Visible (structural metadata)
- Number of items and connections
- Numeric scores or settings
- Account email and timestamps
Each app's specific encrypted vs. visible fields may vary, but the principle holds: your words are yours. The server sees structure, not meaning.
How to verify
- Open your browser's DevTools (
F12orCmd+Opt+I) - Go to the Network tab
- Use the app normally — create or edit something
- Inspect the request payload — you should see ciphertext (e.g.
ENC:...) where your content should be - Check Application > Local Storage — that's where the encryption key lives, never sent to the server
No special tools needed. Every browser has this built in.
Honest trade-offs
Credible Encryption is upfront about what it does and doesn't protect.
Plaintext manifest
Some apps need to send specific data in plaintext to function — an email address for authentication, a prompt for an LLM call. Credible Encryption doesn't require zero plaintext. It requires zero ambiguity.
Every CE-certified app publishes a plaintext manifest: a complete list of every unencrypted field, who receives it, and why. Encryption is the default. Plaintext is the exception, and every exception is declared.
Here's what a manifest looks like:
If a field isn't in the manifest, it shouldn't be leaving the browser. If it's leaving the browser unencrypted, it must be in the manifest. That's the contract.
Badge
Apps that adopt Credible Encryption can display a badge linking back to this page.
Embed it with a single line of HTML:
Trust model
The badge is a claim by the developer. Verification is your responsibility.
The code is already on your machine. Client-side JavaScript is delivered to your browser in full. There's no binary, no compiled blob — you can read every line. Open DevTools, go to Sources, and the encryption logic is right there.
The network doesn't lie. Your browser's Network tab shows every byte sent to the server. If a field contains ENC:... ciphertext, that's what the server received. No server-side process can change what your browser sent.
The key never leaves. Confirm in the Sources tab that the encryption key is derived locally and stored in localStorage. If it's never in a request payload, the server can't have it.
The extension
For users who want the strongest guarantee, the CE browser extension acts as both key manager and verifier — inspired by crypto wallets like MetaMask. Apps work without it. The extension is for people who are serious about privacy.
On first use, the extension generates a 12-word seed phrase with 132 bits of cryptographic entropy — well beyond what any attacker can brute-force. You write it down, and that's your backup. The key lives inside the extension, not in the app. When a CE app encrypts a field, it sends the plaintext to the extension via postMessage, and the extension returns the ciphertext. The app never touches the key.
One key, every app. A single seed phrase works across all CE apps. No per-app passwords, no per-app key management.
No password entropy problem. The seed phrase is fully random — not derived from a password you chose. The full strength of AES-256, guaranteed.
Portable. Install on a new device, enter your seed phrase, and your key is restored.
The extension also verifies encryption continuously. When a CE app encrypts a field, the extension:
- Receives the plaintext from the app via
postMessage - Encrypts it independently using the standard CE parameters and its own key
- Adds the result to a whitelist of ciphertext tokens the app is allowed to transmit
- Monitors all outgoing requests — scans every request body for plaintext leaks or non-whitelisted content
This catches everything:
App sends plaintext? The extension sees the match in the raw request body. Red X.
App encrypts with a different key? The ciphertext won't match the extension's version. Red X.
App leaks to a hidden field? The extension scans the entire request body, not just declared fields. Red X.
App sends data to an undeclared domain? Apps can set a Content-Security-Policy header restricting connect-src to declared domains. When present, the browser itself blocks undeclared requests.
Extension not installed? The app works normally — it derives a key from your password, stores it in localStorage, and encrypts client-side. You can still verify manually via DevTools.
Not a trust exercise — a math check. The extension derives the expected ciphertext independently and confirms the app produced it correctly. If anything doesn't match, you see it immediately.
Secure messaging
CE's baseline protects your data on a server — data at rest. But when an app adds messaging, the problem changes: Alice needs to encrypt something that Bob can decrypt. They have different keys.
The extension solves this too. Each user's extension holds a private key and publishes a corresponding public key to the server. Public keys aren't secret — they can't be used to decrypt anything. When Alice messages Bob:
- Alice's extension downloads Bob's public key from the server
- Extension computes a shared secret using Alice's private key + Bob's public key (ECDH key exchange)
- Extension derives an AES-256 key from the shared secret and encrypts the message
- App sends the ciphertext — the server relays it without being able to read it
- Bob's extension does the same math in reverse — same shared secret, same key, decrypts the message
No coordination needed. Bob doesn't have to be online. The server is just a public key directory and a message queue.
The server sees nothing. It stores public keys and relays ciphertext. It never has private keys, shared secrets, or plaintext.
Forward secrecy is possible. Using ephemeral keypairs per message (as in the Signal Protocol), compromising one key reveals nothing about past or future messages. Each message is independently keyed.
Same verification model. The extension still encrypts, whitelists, and monitors — same architecture, just the key source changes from "my seed phrase" to "shared secret with this recipient."