Security Overview
How end-to-end encryption works on Tessil, and how to report a vulnerability.
Last updated: May 14, 2026
Scope
Tessil is an end-to-end encrypted file transfer service. This page is the security model: what we can and cannot access, how keys are handled, and how to report a vulnerability.
This page describes what we do. If you would rather check than read, verify it yourself walks through four checks you can run against the live site in about two minutes.
Encryption model
- Files, filenames, and the optional transfer title are encrypted in your browser with AES-256-GCM before upload
- The encryption key is generated client-side and lives in the URL fragment (the part after
#) - Browsers don't send URL fragments to servers - the key stays in your browser
- An optional transfer password gates server-side access, independent of the encryption key
- Transfers are deleted automatically when they expire
Sharing links safely
The decryption key lives in the URL fragment - the part after #. Browsers never send fragments to servers; the key
stays local.
The full URL (fragment included) can still land in browser history, browser sync, and bookmarks. Anyone with access to your browser can read a saved link and decrypt the files unless you set a password.
- Share links through trusted, private channels (Signal, encrypted email)
- Set a transfer password for sensitive files - a second factor beyond the link
- Use a private/incognito window if you don't want the link in browser history
- Pick the shortest expiry that still works for your recipient
What we can see
- Encrypted file blobs, encrypted filenames, and the encrypted transfer title (when set)
- Transfer metadata: size, expiry, timestamps
- Operational metadata needed for abuse handling and rate limiting
What we cannot see
- File contents
- Original filenames
- The plaintext transfer title
- Your decryption key
Safeguards
- HTTPS/TLS in transit
- All cryptography runs in your browser before bytes reach the network
- Accounts are optional - anonymous transfers are first-class
- No third-party analytics or tracking SDKs
Optional Accounts
Sign in to manage your transfers from one place. Sign-in is optional. Accounts use magic-link email or a device-bound passkey - no password to remember, lose, or breach. Accounts don't weaken the encryption model: file payloads stay end-to-end encrypted signed in or not, and the encryption key still lives only in the URL fragment.
When you have an account we store:
- Your email address (for sign-in)
- Your account tier (currently free)
- A hashed session token for as long as you stay signed in
- The browser user-agent at sign-in time, for context in your sign-in email
- Authentication events (sign-in requests, successes, sign-outs) - kept for 90 days then automatically deleted
We don't store IP addresses. For sign-in events we record the country and the network operator (ASN) derived from your IP at the moment of the request, plus a rotating cryptographic identifier that lets us correlate suspicious activity within a 24-hour window without retaining the underlying address. The identifier is keyed against a secret we rotate on a 30-day schedule, after which prior events become permanently uncorrelatable.
This applies to every auth-related event. Country and ASN resolution uses MaxMind GeoLite2 loaded locally on our servers; no per-request data leaves the box for this lookup.
The magic-link token and your session cookie are never written to the database in plaintext - both are SHA-256 hashed first. Sign-in links expire after 15 minutes and work once.
Sign-in codes and anti-phishing
Open a sign-in link on a different device than the one you started on, and Tessil shows you a 6-digit code instead of signing you in there. Type the code back on the device where you started.
Tessil will never ask you to share that code. We will never email, call, or message you to request a sign-in code. If anyone - claiming to be Tessil support, a friend, a delivery service - asks for the code, it's a phishing attempt. Don't share it.
The code shows only on the device that opened the link. Never in the email itself, never in any other communication from us.
Passkeys
If your device supports it, add a passkey to skip the email round-trip on sign-in. A passkey is a cryptographic key pair generated and stored by your device's authenticator - Touch ID, Face ID, Windows Hello, a hardware security key, or a synced credential from your platform's password manager.
Passkeys are bound to this site's domain. Your browser only releases a Tessil passkey to Tessil - it can't be used on a look-alike site, even one that copies our design pixel-for-pixel. The browser enforces this (the WebAuthn standard), not us. It's why passkeys resist phishing in a way that passwords and one-time codes cannot.
- The private key never leaves your device (or your platform's secure sync, if you opt in)
- We store only a public key, a credential identifier, and basic device info
- Add, rename, and remove passkeys from your account settings at any time
- Passkeys don't replace email sign-in - both stay available, so a lost device doesn't lock you out
Passkeys don't change the encryption model. File payloads stay end-to-end encrypted, the encryption key still lives only in the URL fragment, and signing in with a passkey only authenticates you to Tessil - it doesn't give us access to your transfers' contents.
Vault for signed-in transfers
When you upload while signed in, your browser wraps the transfer's encryption key under a per-account vault key (Kvault) before sending the wrapped blob to us. The vault key itself never touches our servers - it is derived in your browser from your vault password using Argon2id, and we only store the resulting wrapped blob.
On first sign-in you set a vault password and we generate a 12-word recovery phrase for you to save somewhere safe. Both independently unwrap the vault key: the password is what you type day to day, the phrase is your offline backup if you forget the password. We never see either one in plaintext, so neither can be recovered from us if you lose them.
The vault unlocks once and stays unlocked on this device for up to 24 hours, after which you'll be prompted to enter your vault password again. You can also lock the vault manually from the account menu, which drops the in-memory key immediately.
What this protects: the dashboard can show filenames and rebuild share links for past transfers without keeping any of that information on our servers. Anyone with your account password (or your recovery phrase) gets that same capability - the underlying file payload itself is always end-to-end encrypted under a per-transfer key carried in the share link's URL fragment, separate from the vault.
Responsible disclosure
Found a security vulnerability? Report it privately so we can fix it before public disclosure.
Include reproduction steps, affected URLs, and impact. Acknowledgement within 72 hours.
Attributions
Country and ASN lookups use GeoLite2 data created by MaxMind, available from maxmind.com. The databases are loaded locally on our servers - no per-request data is sent to MaxMind.