Security at Clann
This is the reference page. It sets out what Clann protects, what it does not, how the encryption is built, where the keys live, what our servers can still see, and how to tell us if we have got something wrong. It is written for people evaluating Clann rather than choosing it — reviewers, security researchers, journalists, and the one parent in every family who reads the technical page before anyone else installs anything.
The short answers
Every row below is expanded further down the page. If you are filling in an assessment, this table is the page in miniature.
| Question | Answer |
|---|---|
| Is media end-to-end encrypted? | Yes — every variant, including thumbnails. Default for families created from August 2026. |
| Who holds the keys? | Member devices only. No key of any layer reaches Clann’s servers. |
| Cipher | AES-256-GCM, 1 MiB chunks, OAE2 STREAM. X25519 sealed boxes, Ed25519 signatures. |
| Is location data uploaded? | No. EXIF and GPS are stripped on the device before encryption. |
| What is not encrypted? | Captions, comments, album and member names, and file metadata. Listed in full below. |
| Web viewing | Yes, including for end-to-end encrypted families — an admin approves the browser, which decrypts locally. |
| Encrypted desktop uploads | Yes, via a QR-authorised browser session. |
| Forward secrecy? | No, by design. Explained below. |
| Open source? | Yes — crypto core and protocol spec, Apache-2.0. |
| Independent audit? | None yet. |
| Disclosure contact | security@getclann.com, or GitHub private vulnerability reporting. |
Threat model
The primary adversary is us — the server operator — in two flavours. The first is honest-but-curious: an employee, an attacker holding a database dump or object-storage credentials, or a legal demand. That adversary reads everything at rest. The second is actively malicious: an operator who modifies what your app sees. The second one matters more, because it is the adversary that most products calling themselves end-to-end encrypted quietly fail to consider. If your app trusts our server to tell it a family member’s public key, our server can simply report its own.
We also consider a malicious family member, limited to what they could do beyond the access they legitimately have.
Concretely, the design defends against each of these:
| Attempt | What stops it |
|---|---|
| Server reads photo or video content at rest | Media encrypted on the device under keys the server never holds |
| Server swaps a relative’s encryption key while keeping their identity | An Ed25519 self-signature binds both keys to one account, re-verified by peers before anything is sealed |
| Server swaps your own device’s key back to you | Local pinning — your phone never accepts the server’s word about its own keypair, and refuses to proceed on a mismatch |
| Server injects a device into a key hand-out | An attestation chain from a signed root; an unvouched device blocks the operation rather than quietly receiving a key |
| Server names itself the trust root of a family | The founding device signs a genesis record, verified before any root is honoured; a family whose genesis fails to verify has no root and clients fail closed |
| Server mints its own group key and publishes it as the next epoch | Epoch commitments — the minting device signs the key, and a device refuses to adopt one whose signer is outside the trust graph |
| Server replays a real key as a different epoch, or into another family | Family id and epoch number are bound into that signature |
| A removed member reads new uploads | Key epochs; rotation excludes them from the new one |
| Truncating or splicing an encrypted file | The file header authenticates every chunk, and the final-chunk marker lives inside the nonce |
What is deliberately not protected
A threat model that lists no boundaries is marketing. These are ours, and each is argued rather than merely admitted in the published threat model.
- A compromised member device. A phone that legitimately holds the family key can read the family library. This is true of every group encryption system and is not something cryptography can fix.
- A compromised client build. Nothing here survives an attacker who controls the app you are running, and any protocol claiming otherwise is mistaken about where its trust actually sits.
- First-contact identity. The scheme authenticates keys, not people. That a device belongs to the person it claims is carried by a human approval — the same trust-on-first-use model iMessage uses — backed by an optional six-word safety code comparison and by notifying you whenever a device is added to your account. A device wrongly let in by a person is trusted from then on.
- Metadata. Listed in full below. It is not encrypted and we do not claim it is.
- Forward secrecy within a family. Discussed under membership changes.
- Availability against a malicious member. A member can upload a key package that does not open.
- Deniability. Attestations are signed and durable, and are meant to be.
Encryption architecture
Three tiers. Each layer is wrapped by the one above it. The server holds ciphertext at every layer and a private key at none.
Device identity ── X25519 keypair (encryption) + Ed25519 keypair (signing) │ 32-byte seeds, generated on-device, never transmitted │ │ sealed to each device's X25519 public key one blob per device ▼ Family key ── 32 random bytes per family, versioned by epoch (1, 2, 3…) │ held only on member devices; rotated on member removal │ │ AES-256-GCM wrap ▼ Per-item key ── 32 random bytes per photo or video │ encrypts every variant of that item │ │ CLN1 envelope, AES-256-GCM STREAM ▼ Media bytes
The middle indirection is the load-bearing part. Encrypting files directly under the family key would be simpler and worse: rotating the family key would mean rewriting the entire library, where instead it means minting a new key and re-sealing 32 bytes per device while existing media is untouched. Each item records the epoch it was written under, and anyone holding that epoch keeps reading it.
Per-item keys also bound the damage from any single compromise, and they keep the nonce budget of a long-lived key from accumulating across an unbounded number of files over many years.
The file envelope
Every encrypted photo, video and thumbnail is a CLN1 file: a 32-byte plaintext header followed by authenticated chunks of 1 MiB. Two properties follow from the construction, and they are the reason for it.
- The header is authenticated. It is used as associated data for every chunk, so a server cannot edit the key epoch to point a reader at the wrong key, cannot alter the declared media type, and cannot move chunks between files.
- Truncation is detected. The final-chunk flag lives inside the nonce, so a video cut short at a chunk boundary fails to authenticate rather than decrypting into a shorter, plausible video.
Because chunks are fixed-size, a reader can seek directly to any chunk — which is what makes ranged fetches and scrubbing through encrypted video possible without downloading the whole file.
Algorithms and versions
| Purpose | Algorithm |
|---|---|
| Bulk encryption | AES-256-GCM, 1 MiB chunks, OAE2 STREAM |
| Key wrapping (asymmetric) | Sealed box — X25519 + XSalsa20-Poly1305 + BLAKE2b |
| Key wrapping (symmetric) | AES-256-GCM, 96-bit nonce |
| Signatures | Ed25519 |
| Device fingerprints | SHA-256, rendered as BIP39 words |
| Recovery phrase derivation | BIP39 → PBKDF2-HMAC-SHA512 (2048) → HKDF-SHA256 |
On AES-GCM. XChaCha20-Poly1305 would be the better choice on most axes. AES-GCM is used instead for exactly one reason: it is the only authenticated cipher a browser’s built-in crypto offers, so a browser can handle Clann media with no dependencies and no WebAssembly. The format carries an algorithm identifier and is otherwise cipher-agnostic, so this can change without breaking existing files.
On randomness. No function in the cryptographic library reads ambient randomness. Every operation that needs entropy is handed a random source by the application. That is not an aesthetic choice — the mobile JavaScript engine has no built-in secure random, and a library that silently fell back to a weak source on one platform would fail in a way no test would catch.
Versions. Protocol 1.1; file format CLN1 (version 1, alg 1). Version 1.1 added epoch commitments, closing a group-key injection gap that version 1 documented as a known weakness. That protection applies to families encrypted from that version onwards; families encrypted before it keep their former behaviour, and the two are recorded distinctly rather than guessed at. The full changelog is in the specification.
Key creation and storage
- Created on the device. A device’s entire identity is two 32-byte seeds, generated on that device by the platform’s secure random source. Everything else derives from them. They are never transmitted to Clann, in any form, at any point.
- Stored in platform secure storage, hardware-backed where supported. The seeds live in the platform’s secure store — Keychain on iOS, Keystore-backed storage on Android. How much of that is enforced in hardware varies: Android distinguishes software enforcement, TEE-backed and StrongBox-backed keys by device, and Clann does not currently require a particular tier, so we do not claim one. Family keys arrive sealed to the device’s public key and are held in a local encrypted vault: a single random vault key in secure storage, with the family keys themselves encrypted under it in the app’s local database. Reading them requires both.
- Mirrored into your own cloud, not ours. The seeds are also written to the user’s own platform key sync, and the two platforms differ in a way worth stating precisely rather than averaging out:
- On iOS, seeds sync through iCloud Keychain, which Apple end-to-end encrypts.
- On Android, seeds are backed up through Google Block Store. Block Store provides end-to-end encrypted cloud backup when supported and available on the device — Google conditions it on a recent enough Android version and a screen lock being set, and exposes an API for checking whether it is available. Clann does not currently gate the backup on that check, so on a device without a screen lock the backup may not be end-to-end encrypted. We would rather say that than round it up.
- The seeds are the account. Anyone holding them holds the device’s identity. Where they are stored is the single largest real-world security decision in the system, which is why it is stated here plainly rather than buried.
Adding and removing family members
Key distribution follows membership and never grants it. Being keyed into a family is not the same as being let into one; who is a member is an application decision made by a person, and it is a genuine part of the security boundary.
Adding someone
The family key is handed out by sealing it once per recipient device to that device’s public key. The server stores those sealed blobs and can open none of them. Before sealing anything, the sending device verifies the recipient under one of two policies:
- Self-signature — used only where a person is reviewing the device list at that moment, such as an admin enabling encryption on their own family.
- Attestation chain — additionally requires an unbroken chain of signatures from a trusted root. Used for everything unattended, above all rotation.
There is deliberately no “seal anyway” escape hatch, and no partial hand-out that skips a device that fails verification. Both are worse than failing: sealing to an unverified key is the attack itself, and silently omitting a device locks a real family member out of everything uploaded afterwards with no signal to anyone. For the same reason, granting keys to a new device grants every epoch the family has ever had, never just the latest — a partial grant produces a device that appears to work and cannot open the older half of the library.
Removing someone
Removal flags the family for rotation. The next member device that both holds the current key and has permission mints a fresh key at the next epoch and seals it to the remaining devices under the attestation-chain policy. Our servers cannot perform this, having no key to rotate with, so removal takes effect for new uploads from the moment a capable member device next comes online rather than instantaneously. A device blocked from a family is excluded from hand-outs and refused at every key operation, so it cannot re-admit itself.
The removed person keeps every epoch they already held. They have already seen those photos, and claiming to revoke access to them would be a fiction. They hold nothing that opens anything uploaded after the rotation.
Why there is no forward secrecy
A ratchet provides forward secrecy by ensuring later key material cannot decrypt earlier ciphertext. Clann’s central requirement is that a member admitted today can read the entire library, including everything from before they joined. These are the same property viewed from opposite ends, and no design provides both.
So this protocol optimises for the risk families actually face. The realistic catastrophe is not an adversary decrypting a photo from 2019; it is a grandmother getting a new phone and losing eight years of her grandchildren. Epoch rotation is the compensating control, bounding what a removed or compromised device retains going forward.
Lost devices and account recovery
Losing access is the dominant real-world risk in a system like this. It is far more likely than any attack above, and it is unrecoverable in a way a breach is not — nobody can restore what nobody can decrypt. Three paths exist, tried in order of decreasing convenience.
- Your own new phone restores itself. Because a device’s identity is just two seeds, and the seeds are mirrored into your own Apple or Google key sync, a replacement phone reproduces the same keypair and is cryptographically the same device. The family keys already sitting on our servers unwrap with no approval from anyone. This is the common case, and it is silent.
- A 12-word recovery phrase. The phrase deterministically derives a keypair which is registered as an ordinary device, flagged as virtual. From then on it needs no special handling: every hand-out and every rotation seals to it because it is simply in the device list, so it always holds the current key. Recovery is then not a separate protocol — derive the keypair, unwrap what is already sealed to it, and use that identity to grant to the new phone. The phrase is never stored, never transmitted, and not derivable from anything our servers hold. There is one per account, and registering a new one revokes the old.
- Asking a family member. The universal fallback, and the only one that works for someone who has lost both their phone and their phrase: a device that holds keys grants them to a device that does not, after a person approves. Because it is a human decision, the rules are about roles — letting a new person into a family is an admin decision, approving another member’s new device is an admin decision, and approving your own second device can be done by any accepted member, which is what lets the recovery phrase serve itself.
On the phrase’s key stretching. The derivation uses PBKDF2 with 2048 iterations, which is weak stretching by modern standards. It is adequate here only because the input carries 128 bits of machine-generated entropy — it is not a password, and the construction is not reused for anything a human chose. Stating the reasoning is more useful to an evaluator than stating the number alone.
Metadata exposure
This is the section most worth reading closely, because it is where every honest end-to-end encrypted system has its edges. Encryption covers image and video content. It does not cover the following, all of which our servers can see:
- Captions, comments and album names.
- Family names, member names, avatars, and the membership graph.
- Which families and which items are encrypted, epoch numbers, upload times, ciphertext sizes, media type and image dimensions.
- Every device public key and attestation, and the key-request graph — who asked to be let in, who approved, and when. Browser viewing sessions are part of this: the key a browser was approved with, a coarse label for it, and who approved it.
- Push notification metadata. Encrypted families lose image previews in notifications entirely, because the operating system fetches those and cannot decrypt them.
Put plainly: our servers can tell that a family exists, who is in it, how often they post and how large their photos are. They cannot see the photos. We scope our claims to image content accordingly, and we would rather you read this list here than discover it later.
Thumbnails
Every stored size is encrypted — original, medium and thumbnail, plus video poster images. There is no plaintext preview anywhere in the system, which is the point most worth checking in any product making this claim: generating thumbnails server-side requires reading the image, and a service that does it has, by definition, read your photo. Clann generates every variant on the device before encryption. The visible consequences are the missing notification previews above, and that server-side operations which read pixels are simply not available for encrypted families — the equivalent work happens on the device.
EXIF and GPS
For encrypted families, EXIF and location data are stripped on the device before encryption, so they are never uploaded at all. This is worth distinguishing from the more common arrangement: the data is removed rather than encrypted, which means it is not sitting on our servers in any form waiting for a future decision about it. Camera details and settings go the same way.
The exception is honest and specific: photos uploaded to a family before it switched encryption on may still carry location and subject metadata from that time, unless separately purged.
Backups
- Your photos. The library stored on Clann’s servers is itself the backup — a phone that dies does not take the family’s photos with it. What our servers store is ciphertext, so our own infrastructure backups contain ciphertext too. Restoring one gives us exactly what we had before: files we cannot open.
- Your keys. Backed up by the platform key sync described under key storage, into your Apple or Google account rather than ours, plus the recovery phrase if you save one. This separation is deliberate: the party holding the encrypted photos and the party holding the key backup are different companies.
- What a backup of ours would yield an attacker. Encrypted media, sealed key packages nobody without a member device can open, and the metadata listed above — which is not nothing, and is why that list is stated in full.
What works in a browser
Both viewing and uploading work in a browser, including for encrypted families, and in neither case does a key reach our servers.
- Uploading from a computer works, including to an encrypted family. The page has no Clann credentials and no family key. Both arrive by scanning a QR code with a phone that is already signed in. The browser generates a keypair in page memory, puts the public half in the QR code, and the phone seals the family keys to it. The detail that matters: the key travels through the QR code — specifically through the part of a URL browsers never transmit — rather than being fetched from our API, because a server asked for that public key could offer its own and harvest every family key in the clear. The browser then produces byte-identical encrypted files to the app’s own upload path.
- Nothing is persisted in the browser. The keys live in memory for the lifetime of the tab and are never written to local storage or a database in the browser. Closing the tab destroys them. Re-scanning is cheap; a family key left behind on a shared desktop is not.
- Viewing works too, including for encrypted families. A relative opens the share link and their browser generates a keypair in page memory. An admin is notified, sees who is asking, and approves — and it is their phone that seals the family keys to that browser. We route a sealed package we cannot open, and the photos are decrypted on the reader’s own machine. Sessions expire after twelve hours, an admin can sign a browser out at any time, and once the family’s key rotates an old session cannot open anything uploaded afterwards.
- Compare the six words. Unlike the upload flow, where the browser’s key travels inside the QR code, the approving phone learns it from our servers — so a malicious server could offer its own key instead. What prevents that is a person: six words derived from that key, shown in the browser and again on the phone. If they match, the approval reached the right browser.
Families created before August 2026
Every family created from August 2026 onwards is end-to-end encrypted from the moment it exists, with no setup. Older families are not encrypted until an admin switches it on, and that is a deliberate step rather than an automatic one, because every member’s device has to hold a key before an existing library can be converted. Until that happens, those families are not encrypted, and we would rather say so than let the word cover both cases.
When an older family does switch it on:
- New uploads are encrypted immediately, from the moment they leave the phone.
- The existing library is migrated too, not just new photos. The work happens on a member’s device, since we never hold the key, and runs through the library in the background.
- Photos carry the location and subject metadata they were uploaded with until they are migrated or purged, as noted under EXIF and GPS.
- Families encrypted before protocol 1.1 keep the earlier behaviour on epoch provenance, so the group-key injection scenario that version closed remains possible for them. Which kind a family is, is recorded when it is encrypted and cannot be cleared afterwards, and clients refuse to be talked down onto the older path.
How to check any of this
Everything above is a claim. These are the things you can check without taking our word for it.
- The source on GitHub → — the cryptographic implementation, Apache-2.0, with its test suite.
- PROTOCOL.md → — the normative specification this page summarises: key hierarchy, file format, device identity, group key exchange, recovery and the full list of scope boundaries.
- A demonstration you can run → — encrypt a photo in your own browser with the same published library the app uses, then try to get it back.
- Cross-implementation test vectors. The file-format vectors are generated by an independently written Go implementation and reproduced byte-for-byte by the published one. A round-trip test proves only that a codec agrees with itself; two independent implementations agreeing on bytes is what actually pins a format.
- Asserted negative properties. The suite asserts the failures directly — that truncation fails, that chunks cannot be spliced between files, that a server-minted device is refused under the strict policy, that a removed member cannot open a post-rotation epoch, and that a key with no commitment, a key signed by an untrusted device, a genuine signature reused over a substituted key, and a signature replayed from another epoch or family are each refused.
Audit status
Clann’s cryptography has not been independently audited. As of 19 August 2026 there is no third-party audit report, and we will not describe the things above as a substitute for one. Publishing the implementation, the specification and the threat model lets a reader check the design; cross-language test vectors pin the format; neither is an audit.
We would rather state this plainly than let a page full of algorithm names imply otherwise. If an audit is commissioned, the report will be linked here and this section will say so with a date. Independent review is welcome in the meantime — see below.
Reporting a vulnerability
Report security issues privately, by email to security@getclann.com, or through GitHub’s private vulnerability reporting on the repository. Please do not open a public issue for anything you believe is exploitable.
Useful things to include, in rough order of value:
- what an attacker gains, and what they need in order to get it;
- which file and function the problem is in;
- a proof of concept, or a failing test — the repository’s test suite is a good template, and a failing test is the fastest possible route to a fix.
We will acknowledge within a few working days and keep you updated as we investigate. If you would like credit in the changelog, say so; if you would prefer not to be named, that is fine too. We do not run a paid bounty programme.
Scope
In scope: everything in the cryptographic repository — the file envelope, the sealed-box construction, the identity and attestation logic, the group key exchange, the epoch commitments that authenticate it, and the recovery derivation. Also in scope: any place the code does not deliver a property the specification claims. The highest-value finding available is a group key a client will adopt without a valid commitment from a trusted device.
Also in scope, reported to the same address: the Clann application, its servers and its infrastructure. Those live outside the open-source repository, so send them by email and we will route them.
Known already. Please still report these if you have something new, but they are documented rather than overlooked: grant-time trust propagating into the attestation chain, so a device admitted by a bad human approval is treated as trusted from then on; metadata not being encrypted; wrap verification happening on clients rather than the server; no forward secrecy within a family; and a compromised member device being able to read its families. If you think the reasoning behind one of them is wrong, or can sharpen one into something more serious than we have it, that is a genuinely useful report — an ordinary issue is the right place. The full policy is in SECURITY.md.
Common questions
No. As of August 2026 the cryptographic library has not been externally audited. The implementation and the protocol specification are published so that anyone can review them, the file format is pinned by test vectors generated from a second, independently written implementation, and the test suite asserts the negative properties directly — but none of that is a substitute for an independent audit, and we do not describe it as one. Independent review is welcome.
Not the photos or videos, at any size, including thumbnails. Our servers can see that a file exists, who uploaded it, when, which family it belongs to, its size, its media type and its dimensions; the membership of the family; group names, member names and avatars; captions, comments and album names; every device public key and the record of who asked to be let in and who approved. Location is removed on the device before an encrypted upload and is never received at all.
On devices only. Each device holds two 32-byte seeds generated on that device by the platform CSPRNG, which never reach Clann’s servers. Group keys arrive sealed to a device’s X25519 public key and are stored locally in an encrypted vault. The seeds are also mirrored into the user’s own platform key sync — the user’s cloud account, not ours. On iOS that is iCloud Keychain, which Apple end-to-end encrypts. On Android it is Google Block Store, which provides end-to-end encrypted cloud backup when supported and available on the device, conditioned by Google on a recent enough Android version and a screen lock being set.
The group is flagged for rotation, and the next member device that both holds the current key and has permission mints a fresh group key at the next epoch and seals it to the remaining devices under the strictest verification policy. The removed person keeps the epochs they already held — they have already seen those photos — and holds nothing that opens anything uploaded afterwards. The server cannot perform the rotation itself, because it holds no key.
No, and deliberately not. Forward secrecy means later key material cannot decrypt earlier ciphertext. Clann’s central requirement is the opposite: a grandparent admitted today must be able to read the family’s entire history, including photos from before they joined. No design provides both. The compensating control is epoch rotation, which bounds what a removed or compromised device can read going forward.
Yes, both. A relative opens the share link and their browser generates a keypair in page memory; an admin approves from their phone, which seals the family keys to that browser. Clann’s servers route a sealed package they cannot open, and decryption happens on the reader’s own machine. Both screens show the same six words, and comparing them is what stops a malicious server substituting its own key. Sessions expire after twelve hours, can be revoked from the app, and go dark for new uploads once the family’s key rotates. Uploading from a desktop browser works the same way, authorised by scanning a QR code.
Email security@getclann.com, or use GitHub’s private vulnerability reporting on the clann-e2ee repository. Please do not open a public issue for anything you believe is exploitable. Include what an attacker gains and what they need to get it, where the problem is, and a proof of concept or failing test if you have one. We acknowledge within a few working days. Credit in the changelog is offered and entirely optional.
A compromised member device, an adversary controlling the client build, first-contact identity (a device is authenticated cryptographically, but that a device belongs to the person it claims is carried by a human approval), metadata, forward secrecy within a group, and deniability. Each is documented in the published protocol rather than left for a reader to discover.
Share family photos without an audience
Free to download.
