7key Privacy

Threat model

What 7key protects, against whom, and where the protection ends. The mechanisms behind each claim are in Cryptography; the tests that enforce them are listed at the end.

Assets

  1. Vault contents: site names, URLs, usernames, passwords, 2FA secrets and notes.
  2. The master password, which opens the vault on any device.
  3. Shared items, while a link is alive.
  4. Metadata: who has an account, how many items, when they sign in.

Parties

PartyAssumed capability
Network attackerReads and alters traffic outside TLS
Server operatorReads D1, reads and changes Worker code and secrets
Database thiefHolds a copy of D1, nothing else
Malicious websiteRuns script in a page the user visits
Link carrierThe chat or email service that transports a share link
Breach-check serviceHave I Been Pwned, when the user runs the check
Icon serviceDuckDuckGo or Google, asked by the Worker for logos
Device thiefHolds a powered-off or locked device
Malware on the deviceRuns code as the user while the vault is unlocked

What each party can learn

PartyVault contentsMaster passwordMetadata
Network attackerNo: TLS, and the payload is ciphertext anywayNoTiming and size of requests
Database thiefNoNo offline guessing without AT_REST_SECRETEmails, item counts, timestamps
Server operatorNo, as long as the extension is honest (see below)Can guess offline at 600,000 PBKDF2 iterations per guessEverything the database holds, plus IP addresses in logs
Malicious websiteOnly a login the user explicitly fills there, and only on its own domainNoWhether autofill is on
Link carrierThe shared item, unless a passphrase was set and sent separatelyNoThat something was shared
Breach-check serviceNo: it receives 5-character SHA-1 prefixes, each shared by hundreds of passwords, with padded responsesNoThe user's IP address and that a check ran
Icon serviceNoNoDomain names, from the Worker's address, not the user's
Device thiefWith auto-lock on "Never", yes while the session is valid; otherwise no, the local copy is ciphertextCan guess offline against the cached wrapped keyEmail, item count
Malware on deviceYes, once unlockedYes, if it logs keystrokesYes

Exported files

An encrypted export is as strong as its passphrase: PBKDF2-SHA-256 with 600,000 iterations and AES-256-GCM, with a fresh salt per file. Anyone holding the file can guess the passphrase offline at that cost, so 7key requires at least 10 characters. A CSV export is plain text and offers no protection once copied.

What the server learns

The server, and so anyone who operates or breaches it, learns:

With website icons on (the default), the server also sees the domain of each saved login while it fetches that site's logo. It does not store them, and the extension keeps fetched logos in memory only, never on disk. With the option off, the server never learns site names. It never learns URLs, usernames, passwords, 2FA secrets, notes, or the contents of a share.

Out of reach, by design

A forgotten master password. Nobody holds a copy and nothing can unwrap the vault key without it. A recovery mechanism is a second way in, available to whoever controls it.

Malware on an unlocked device. Code running as the user can read the extension's memory, the screen and the keyboard. No client-side design survives a compromised endpoint.

The link carrier. A share link's fragment is its key. The service that carries the link can read it like any other text. A passphrase delivered over a different channel closes this, at the cost of a second message. See Share links.

A malicious server and an honest-looking extension update. The extension's code decides what it sends. An operator who also ships the extension can ship one that sends keys home. Self-hosting from source you have read, or building the extension yourself, is the defence. A Chrome Web Store build is only as trustworthy as its publisher.

A malicious server and the web dashboard. The dashboard at /app is code the server sends on every visit. An operator, or anyone who takes over the server, can send a version that leaks the master password or keys of whoever signs in next. Only organization admins need the dashboard; the extension covers the same tasks without this exposure.

Server-side rollback. A server can return an older copy of an item, or withhold a newer one; the extension cannot tell. Integrity of each item is protected, freshness of the whole vault is not.

Metadata. The list above is accepted for a personal password manager. If hiding who uses the server or when matters to you, this design is not enough.

Specific defences

ThreatDefence
Login request reveals the vault keyAuth key and wrapping key are separate HKDF outputs
Leaked database used to guess passwordsAuth hash and wrapped key keyed by AT_REST_SECRET, which is not in D1
Online password guessing10 failures per email per 15 minutes, then a 15-minute lock; 30 requests per minute per IP
Finding out which emails have accountsprelogin returns stable decoy parameters for unknown addresses; login timing is uniform; sign-up sends a different email instead of an error
Strangers using a personal serverAccount creation needs REGISTRATION_TOKEN unless open registration is chosen
Flooding a shared serverPer-network daily account limit, per-account item and write limits
Server swaps ciphertext between items or accountsItem id and account id are AES-GCM associated data
Stolen session token replaces the passwordChanging the password or deleting the account needs the current auth key
Stolen session token survives a password changeChanging the password revokes every session
Leaked database yields usable tokensOnly SHA-256 hashes of session and revoke tokens are stored
Two people opening a single-view link at onceThe view is claimed in one conditional UPDATE … RETURNING
Probing a share's recipient listRequesting a code returns the same answer for every address
A page impersonating another site to autofillThe service worker uses the URL Chrome reports for the sender's top frame
A page clicking autofill on the user's behalfEvery action requires a trusted user event; the UI is in a closed shadow root
A page using another site's passkeyThe RP ID is checked against the top-frame origin Chrome reports, no broader than its registrable domain; clientDataJSON carries the real origin
Copied password left on the clipboardCleared after 30 seconds by the service worker, even after the popup closes
Vault key written to diskOnly sealed under a key the server holds per session, and only with auto-lock on "Never"; deleted on lock, sign-out or a revoked session
PIN guessed on a stolen laptopThe sealed vault key needs both the PIN and a key the server releases only for the right PIN; five wrong tries wipe it, and the session ending, sign-out or a password change ends it too
Biometric unlock replayed or forgedThe server releases the key only for a signature over a fresh one-time challenge from the key pair the platform authenticator created, with user verification; the sealed copy also needs a secret that stays on the device
A copied session token while PIN or biometric unlock is onThe token stays on disk while the vault is locked, so a copy of the browser profile can call the API until the session ends: list, delete or roll back items to older ciphertext from the same disk. It cannot read anything or unlock the vault, and signing out or changing the password ends it
Script injection or framing on the share pageStrict CSP, frame-ancestors 'none', password never placed in the DOM
Supply-chain attack through dependenciesNo dependencies in src/core; QR codes read with the browser's built-in BarcodeDetector

Verifying the claims

The strongest statements above are enforced by tests:

npm test

The project has not had an independent security audit.