Your API data is naked the moment TLS ends
HTTPS protects your data in transit — and does it perfectly. But the instant TLS terminates, the JSON body lies in plaintext across your logs, databases, CDN, proxies, and every third-party hop. Nen keeps it encrypted the whole way. One line of code. Same TLS you already trust.
fetch("/api/claims", {
method: "POST",
body:});
TLS did its job. Then it handed off your plaintext.
TLS encrypts the channel and stops at termination — the load balancer, the CDN edge, the serverless runtime. From there your payload travels in the clear. This isn't a flaw in TLS; it's simply where TLS's job ends. It's where Nen's begins.
You already wrote 90% of this
Swap fetch for nenFetch on the client. Wrap your route with withNen on the server. The handshake, key rotation, HMAC, and replay protection happen underneath. About ten lines, start to finish.
import { nenFetch } from "@withnen/client";
const res = await nenFetch("/api/claims", {
method: "POST",
body: JSON.stringify(claim),
});
// payload encrypted before it leaves the tabimport { withNen } from "@withnen/server";
export const POST = withNen(async (req, body) => {
// body is already decrypted + verified
return { ok: true };
});
// payload decrypted and ready for processing
No overclaims. Ever.
A security engineer will find any exaggeration in thirty seconds — so we draw the line ourselves.
Everything between the two Nen endpoints sees only ciphertext. The two endpoints hold plaintext — by necessity, because someone has to read the data. The product's value is letting you choose where those endpoints are, pushing the trust boundary inward past the CDN, edge, load balancer, logs, and proxies — down to the specific code that genuinely needs the plaintext.
What we will never claim: “even a compromised server sees only ciphertext.” The terminating server decrypts — that is the point of the middleware. See the full threat model for what Nen does and does not protect against.
What that one line actually does
Behind nenFetch is a full post-quantum handshake: an ML-KEM key encapsulation, an optional ML-DSA identity signature, and a derived ChaCha20-Poly1305 session. Run it step by step — change the payload, change the security level, and watch the ciphertext change with it.
Designed for the edge.
Built to be ignored.
Post-quantum cryptography sounds slow. We made it invisible. Nen sustains thousands of encrypted requests with sub-millisecond crypto overhead.
Sustained Throughput
Nen is highly optimized for concurrent workloads. Built-in session caching and efficient key derivation means the server scales effortlessly across thousands of active connections without sacrificing latency.
Microsecond Overhead
By leveraging native bindings and optimized WebAssembly for ChaCha20-Poly1305, encrypting payloads takes fractions of a millisecond. Our wire format adds minimal base64 padding.
| Payload | Plaintext | Wire Size | Overhead | p50 Latency | p99 Latency |
|---|---|---|---|---|---|
| 1KB | 1.0 KB | 1.5 KB | 1.437x | 1.486 ms | 4.969 ms |
| 10KB | 10.0 KB | 13.5 KB | 1.344x | 1.72 ms | 9.158 ms |
| 100KB | 100.0 KB | 133.5 KB | 1.334x | 5.654 ms | 19.918 ms |
| 500KB | 500.0 KB | 666.8 KB | 1.334x | 21.487 ms | 29.842 ms |
Real-World Scenarios
We don't just benchmark simple loops. We evaluate Nen against demanding application patterns like session churn, connection bursts, and extended lifetime sessions to ensure stability.
Concurrent Handshakes
Sustained ML-KEM-768 handshakes per sec during peak burst (C=50).
Key Rotation
p50 latency to renegotiate keys mid-session while under load. Normal requests stayed at 25.943ms.
Long-Lived Sessions
Negligible latency drift over 1.8s session (1000 reqs). Growth: 147.64MB.
Multi-User Burst
Aggregate throughput when 100 distinct users simultaneously execute full CRUD lifecycles.
Session Churn
Sustained create/destroy cycles per second over 2540 sessions. 0 errors.
Encrypt LLM prompts across your own stack
AI apps stream prompts, PHI, legal context, and financial records through many hops of your own infrastructure. Nen keeps prompts and streamed tokens as ciphertext from the user's browser to the one backend service you trust to call the model.
Honest scope: this hides prompts from your edge, logs, and proxies. It does not hide them from the model provider — they must decrypt to run inference.
See the Secure AI pageconst ai = createSecureOpenAI({ /* ... */ });
const stream = ai.chat.completions.stream({
messages,
});
// prompts and streamed tokens are E2E-encrypted
// from the browser to YOUR backend — your edge,
// CDN, logs, and proxies see only ciphertext.Who reaches for this
Security and platform engineers at fintech, healthtech, and AI companies who just got a PQC-readiness or data-handling audit questionnaire — and need documentation and proof as much as code.
Features
Post-quantum key exchange
ML-KEM-768 (FIPS 203) for the handshake and ML-DSA-65 (FIPS 204) for opt-in identity. Recorded ciphertext stays safe against harvest-now-decrypt-later.
Base64 wire format
The Wasm core outputs base64 directly — under 1.4x wire bloat versus raw, not the ~4.9x of number-array serialization.
Mandatory per-request HMAC
Every request is signed and verified with HMAC-SHA256 over METHOD, PATH, TIMESTAMP, and NONCE. HMAC is mandatory — the auth-downgrade bypass is closed.
Edge-ready sessions
Pluggable SessionStore with in-memory, Redis, and Upstash (REST, no TCP) backends — stateless horizontal scaling, including Edge runtimes like Workers and Vercel Edge.
Encrypted SSE streaming
nenStream encrypts each chunk with ChaCha20-Poly1305 and an XOR-counter nonce, decrypting tokens as they arrive.
Drop-in integration
withNen middleware and nenFetch client for Next.js App Router — about ten lines from npx create-nen-app to a working handshake.
Keep TLS. Add the part it can't reach.
The free SDK gives you the protection. The docs give you the proof your auditor wants. Both ship today.