AVANOAvano
Limits

Everything this cannot do, in one place.

This used to be a paragraph repeated in the footer of twenty-five pages. A caveat printed twenty-five times is a caveat nobody reads, so it is one page now, argued rather than recited — and it is the page we would read first if we were you.


01 — Position Six admissions a serious reader should weigh

Avano is pre-release software. These are the six things that costs you.

No audit

Nobody independent has reviewed our code.

libsignal — the cryptography we build on — is independently audited. Our own additions are not, and that is where every distinctive claim on this site lives. An external audit is on the roadmap; until it happens we will not imply an assurance we do not have. "Built on audited cryptography" is not the same sentence as "audited".

Closed source

The source is not published.

The repository is private. A LICENSE file carrying the full AGPL-3.0 text was added on 29 July 2026; until that day the licence existed only as a metadata field in thirty-five build manifests, which grants a reader nothing at all. That is fixed, and it does not make the source public — the two are separate, and only the second one matters to you. Until the repository is public, every architectural claim we make is one you take on our word, including the ones we are proudest of. The app's own trust screen reads Open-source · PLANNED and this site agrees with it. Publishing is the single change that would move most of the proof page at once.

One open licensing question, since we found it ourselves and it is not resolved. We declare AGPL-3.0. libsignal, which supplies every piece of our message cryptography and is not optional, declares AGPL-3.0-only. The or-later half is a grant we may not be entitled to make over a combined work that links it, which would mean our own declaration claims more than we hold. Which position is correct is a question for counsel rather than for an engineer, and it is on the register of things counsel has not answered.

Distribution

This is our weakest link, and we know exactly why.

The build is hand-made, signed with a development key, delivered by hand, with no published hash and no public log. We are not in an app store, there is no update channel, and there is no way to revoke a bad build — including ours. Every comparable service that was broken was broken here: EncroChat through a pushed update, ANOM through the distributor, Ghost through the administrator's own software updates. Not one went through the cryptography.

The split

One relay runs. A second is planned, not deployed.

Relay one is in Germany. A second relay ran in Iceland — a different company, network and jurisdiction — and was deliberately allowed to lapse in early August 2026. The app never dialled it: it pins a single relay. A diverse-jurisdiction second relay, sited outside Europe, is planned but not deployed. A liveness claim in the present tense is exactly the shape that goes stale without anything failing — this very page used to say "two relays exist" after one had already lapsed, which is the mistake it now warns about.

The routing that splits the two sides of a conversation across two relays is written and is not switched on, so today one legal order reaches one operator and that is sufficient. Both Android and iOS state the real posture per conversation rather than letting you assume it.

The crowd

Anonymity is a property of a crowd, and ours is small.

This is the one weakness on the page that no engineering closes. A large, boring population to hide inside is worth more than most mechanisms, and Signal has one. We do not, yet. Growth is the only fix and we are not going to pretend it is a feature.

The web view

The interface is rendered by the system web view, not written in native code.

A web view is a wider attack surface than a native UI, and against an adversary who already runs code on the device — commercial spyware of the Pegasus and Predator families — that is a real cost of how the app is built today. Under that adversary every messenger reads the plaintext after decryption anyway, so it changes the price rather than the outcome. It does change the price.


02 — Device Adversary: a forensics lab with your phone on the bench

What a forensics lab actually gets.

The honest answer has two halves and the second one is not comfortable.

If the app was locked

Message bodies, identities, session state, the contact list and group membership are sealed and stay sealed. The seal key is an Argon2id entanglement of a hardware-held key and your passphrase, so extracting the device key on its own yields nothing.

What it still gets

The whole-file encryption our own specification mandates is not in use — the vendored build fails on our target — so per-column sealing is what protects the contents and it can never protect the container. A lab reads the schema, the table names, the indices and the row counts. Row counts are not nothing: they say how many contacts you have and how many messages you exchanged. Beyond that, a small list stays readable by design, because the code needs to compare or sweep on it: your account public key, prekey identifiers, a per-contact device identifier, message sequence numbers, and expiry timestamps quantized to fifteen minutes.

So the accurate sentence is: the contents of the database are sealed; the shape and volume of it are not.

Do not rely on the duress features

Avano has a duress passphrase that wipes and opens an empty decoy, and a wipe-after-N-attempts counter. Neither is ready to be trusted under coercion. Both are gated on an unauthenticated sidecar file, so deleting that file disables the defence and nothing records that duress was ever armed. Worse, the decoy is distinguishable: the sidecar vanishes, and because the duress path skips the attempt counter the decoy database's modification time is far newer than its own key header, which never happens on a genuinely fresh account. A detectable decoy under coercion is worse than none, which is why this paragraph exists instead of a feature bullet.

And nothing here protects you from being made to unlock it. No app can do that. The passphrase lock protects a phone that was put down; it does not protect you from a person, a border officer or a court. Once code runs on the device with the app's privileges or above, it reads the message after decryption — the same way it would read any messenger, or photograph a notebook.


03 — Relay Adversary: the operator, compelled

A RAM image captures the present. A disk image captures the past.

That sentence is why our relays write nothing to a disk, and it is also the honest statement of what that buys and what it does not. A warrant for the disk returns nothing and a subpoena for backups returns nothing, because there is nothing there. A copy of the running machine's memory is a different question. It yields the queues that exist at that instant: sealed, identical-size blocks under random codes, with no sender field, no account and no link between two queues — but it is a real capture and we are not going to describe it as an empty one.

What a relay can still work out over time, without decrypting a byte, is the honest residue of the design. It sees roughly an eighth of your inbound queues on each of your eight connections, and because connection co-occurrence only accumulates, it learns each leg's whole membership within a few polling intervals — no amount of timing work undoes that. It gets the complete set back at every lock and unlock boundary, which is now the largest single piece. And a relay that is also watching a burst of file chunks arrive back-to-back can group them and estimate the file's size, even though nothing it stores says which pieces belong together.

What we can be ordered to build

A court can order an operator to start logging. It cannot order us to produce what was never written down, but it can order the next version to write it down. That is a real limit of any hosted design and the intended mitigation is structural rather than promissory: two relays under two companies in two jurisdictions, so one order reaches only one of them. That mitigation is not in force today — one relay runs and the app dials it, and the second is not deployed; see the split row above. We do not run a warrant canary, deliberately, and the reasoning is published.


04 — The floor Adversary: one who watches both ends

The attack that defeats every deployed messenger, including this one.

An opponent who can observe the network at both ends of a conversation confirms it by timing alone, without reading a byte and without breaking anything. They watch your link, they watch the other person's link, and they correlate. Tor does not stop it, cover traffic does not stop it inside a session, and no messenger that has ever shipped stops it.

We say this here rather than let you discover it, because the people this product is for are exactly the people who might have such an opponent. Avano minimizes metadata by design. It cannot make anyone anonymous against every adversary, and we will never call it untraceable, invisible or anonymous — those words are false, and every operator who marketed one was prosecuted for the posture rather than the code.

An overstated security claim is worse than no claim, because a user acts on it.The rule this codebase's engineering documentation is organised around

05 — Unwired The defect this project keeps finding in itself

Built, tested, documented — and called by nobody.

This is our characteristic failure and we would rather name it than have it discovered. A defence gets designed, implemented, documented and covered by a passing test — and nothing in the shipping app ever calls it. The tests pass because the tests call it. On one day in July a single review found eighteen instances.

There is now a guard that fails the build when a security module has no production caller, and it has itself been corrected three times by findings from outside it, because a check is not self-validating. Here is what is currently in that state and reachable by no app:

Address rotation

Each contact already reaches you on a different private queue, so no relay sees one address that is you. Rotating those queues over time is engine-complete and app-absent — no timer, no drain hook and no user action anywhere reaches it. Until it is called, a queue is long-lived.

Engine only
The two-relay split

Written, machine-checked, and not switched on. The app hardcodes one relay and no signed directory is published, so relay selection degrades to the pinned relay on every open — honestly, and by design, but it degrades.

Not on
Group eviction

An authoriser can now remove a member, and every other device stops addressing them — a removed member's queue gets nothing. But there is no group key to rotate, so this is roster agreement, not cryptographic post-compromise security. Separately, the membership graph leaks over time: repeated deposits into stable queue ids within milliseconds recover group size and membership over a few hundred messages. The defence for that is temporal and none of it is in the tree.

Missing
Abuse reporting

Every message carries a franking commitment the recipient re-checks, which binds honest senders using the stock client. It does not bind a malicious one: a modified sender that simply omits the commitment is accepted as unfranked. Closing that needs franking to be mandatory once the fleet has moved.

Partial
iOS verification

iOS compiles, builds, installs and runs — it has since 24 July 2026. But our continuous-integration account is suspended, so no workflow runs and iOS is verified by hand, on a rented Mac, per session, with nothing re-checking it in between. Read any iOS claim as verified on request, not as continuously verified.

By hand

06 — Status Four buckets, and things move between them

What works today, and what does not.

CapabilityAndroidiOSState
One-to-one messaging over the networkRunsRunsLive
Pairing by one-time sealed linkRunsRunsLive
Post-quantum handshake and ratchetRunsRunsLive
Tor for every message (calls excepted)RunsRunsLive
Cover polling (inbound), free, on by defaultRunsRunsLive; outbound decoy half not built
Sealed store, passphrase lock, auto-lockRunsRunsLive
Disappearing messagesRunsRunsLive
Small groups (max 32)RunsRunsLive; add / remove / rename / transfer
Files and photos, metadata strippedRunsRunsLive
Per-conversation split indicatorRunsRunsLive
Two-relay routingWrittenWrittenNot switched on
Address rotationEngine onlyEngine onlyNo app caller
QR pairingNo decoderNo decoderNot shipped
Message searchPlanned, index refused
Voice calls (one-to-one, relayed)RunsBuiltVoice built, audio unverified; video not built
Push service · backup · public channelsRefused
Build signing keyDebug keyPre-release only
Independent security auditNone yet
Published sourceNot yet
App store distributionNot yet

Three sentences this table exists to keep true. A capability is only Live if a shipping app reaches it — an engine that can do a thing and an app that calls it are different claims, and confusing them is this project's signature defect. Refused and Not yet are different columns, and the difference is on refusals. Nothing moves up a bucket without something outside the module confirming it.


Next

If you found this page convincing, the next one is the test.

Anyone can publish a list of their own weaknesses. The harder question is which of the strengths you can confirm without taking our word for anything.