Security
Your test data is encrypted with a key we don't have
Testrim is designed so that a breach of our servers, a subpoena to our cloud provider, or a malicious insider at Testrim itself yields ciphertext — never plaintext storageState, never plaintext test source, never plaintext run output.
The invariant
The Testrim server can never decrypt your storageState.json, your test source, or any run-time artifact on its own. Plaintext exists only inside your runner, in RAM, for the duration of a single test execution.
Every other defense — Firecracker microVM isolation, mTLS, attestation, FedRAMP controls — is layered on top. The invariant is the load-bearing claim.
How it works
Two secrets protect your vault, both derived locally in your browser:
- 1.Master password — what you type. Lives only in your head.
- 2.Secret Key — 128 bits of randomness generated by your browser at signup, downloaded as a text file you save locally. We never see it.
Your Master Unlock Key (MUK) is derived from both:
Salt = SHA-256(account_name) K_password = PBKDF2-HMAC-SHA256(password, Salt, 650,000 iterations) K_secretKey = HKDF-SHA256(Secret Key, "testrim-2skd-v1:" + account_name) MUK = K_password XOR K_secretKey AuthKey = HKDF-SHA256(MUK, "testrim-auth-key-v1")
The MUK encrypts every test artifact with AES-256-GCM. The AuthKey is sent to us (hashed at rest) so we can mint a login session. The MUK itself never leaves your browser.
What we cannot decrypt
| Asset | Where plaintext lives |
|---|---|
| Master password | Your head |
| Secret Key file | Your local disk |
| Master Unlock Key (MUK) | Your browser RAM and your runner RAM, briefly |
| storageState (cookies, localStorage) | Your runner RAM, for one test |
| Test source code | Your runner RAM, for one test |
| Run-time screenshots / traces | Your runner RAM (we store only metadata: pass/fail, duration, ciphertext fingerprint) |
What this defends against
- External attackers — credential stuffing fails because PBKDF2-650k makes offline password guessing infeasible. Reading our database yields ciphertext.
- Cross-tenant breaches— every query is scoped by account ID from the session. Customer A cannot see customer B's targets, tests, or runs.
- Malicious Testrim insiders — engineers with full production access cannot decrypt customer data. There is no "master key" they can use.
- Compromised cloud provider — AWS GovCloud insiders, a National Security Letter, or a state-actor compromise yields ciphertext only.
- Schrems II / EU data sovereignty— customer-held keys mean the cloud provider's jurisdiction is irrelevant.
- Test-source sandbox escapes — production tests run in Firecracker microVMs with KVM-enforced hardware isolation. Compromise of one test does not compromise the host, other tests, or other customers.
Compliance roadmap
For security teams
We publish our threat model and architecture under /docs inside the product's git repository. Auditors and buyer security teams should start there.
docs/ARCHITECTURE.md— system design, sequence diagrams, prototype-vs-production statedocs/THREAT-MODEL.md— STRIDE-style threat analysis, attacker classes, residual risksdocs/COMPLIANCE-ROADMAP.md— quarter-level milestones, cost, gating dependencies
Responsible disclosure
If you find a security issue in Testrim, please email [email protected] with details. We commit to a 5-business-day initial response and will work with you on a coordinated-disclosure timeline.
We do not currently run a paid bug bounty. We will publicly acknowledge researchers who report valid issues.