AeroVault Wrapper-Stack and Cryptography: Design Conversation #276
Replies: 11 comments 36 replies
-
|
I have plenty of more things to add on this topic, but I want to make sure we agree on the organisation first so I know where's the right place to post what. Perhaps you forgot, but I thought we agreed in #271 (comment) to keep #272 as a roadmap exclusively for the wrappers/overlays, and offshoot anything that's exclusive for AeroVault to its dedicated repo. So I didn't expect this comment as a separate post, as I thought you might post a comment like this in #272. If you agree, please rename #272 to "[ROADMAP] Wrappers/Overlays" or a similar name when you're ready, and also make a "[ROADMAP] Mobile App 📱". Although, the latter is of course less of a priority and I don't plan on posting anything on it for a while, but again, I have big ideas there as well. I can think of at least one more idea for another [ROADMAP], but I want to definitively hear that you agree to this structure before opening it as well. |
Beta Was this translation helpful? Give feedback.
-
|
Quick security update for this thread. The current AeroVault format version is now v3, shipped in the standalone crate Why v3 landed now: the deep audit surfaced a chunk-splicing gap (CRYPTO-01). The old per-chunk authentication bound only the chunk index, reset per file under one master key, so someone who could already edit a vault could swap one file's chunk for another's and have it still extract as authentic. v3 binds a per-file random id plus the chunk count and index into the AEAD, on both the inner layer and the cascade, encrypt and decrypt. The file id lives in the AES-SIV-encrypted (authenticated) manifest and the version byte is under the HMAC-SHA512 header MAC, so neither can be stripped to force the old path. This was a security-driven step; the larger wrapper-stack work continues on its own track. Verified before shipping: the crate test suite, real round-trips (v3 and v2 both byte-identical, tampered vaults rejected), and a cross-tool round-trip uploading a vault from AeroFTP and pulling it back with rclone, no regressions. On where this lives: I hear your point about keeping AeroVault in its own repo. The 0.4.0 changelog is committed in |
Beta Was this translation helpful? Give feedback.
-
|
@EhudKirsh bringing the Error Correction design here into the AeroVault design thread, since this is the home you and I set for AeroVault design follow-ups. The track itself was opened in the roadmap (#272, section 4). This post reports what is actually built, makes good on the naming point you raised, lays out the placement decision with the full trade matrix and the reasoning behind every call, and puts the open questions in front of you for the pre-tag review pass we agreed on. Nothing here is tagged or in a release. This post is the review surface, on purpose, and everything in it is open to revision, not presented as closed. Status: development is underway on a working branch (not pushed, not tagged). What is built and green on local gates right now: the embedded Reed-Solomon layer over the cipher blocks (create / scrub / repair, CLI and GUI), and, new since I started this write-up, the metadata-locator protection in section 4 (a corrupted manifest is now rebuilt from its own parity instead of being fatal, with a regression test). The optional detached placement (section 3) is the next slice and is presented here as design for your review before it lands. I am sharing this now to inform and to get your read; the testable release still waits for your review pass, per section 6. 1. Naming: the acronym is goneYour point from the 2026-05-29 comment: stop using "ECC" for Error Correction, because in a thread full of cryptography it collides with Elliptic Curve Cryptography, and the second C was never well justified. You are right and I agreed. The whole surface is moving to "Error Correction" spelled out: UI strings, CLI help, the docs, and the code symbols and on-disk identifiers too, so the acronym does not survive anywhere a user or a reviewer would read it. If you still spot "ECC" after this lands, it is a miss; flag it. 2. The format decision: v4 is v3 plus Error Correction, not a new formatYou framed this exactly right in May: "V4 will simply be V3 plus these added Error Correction files, which a V3 version of AeroFTP can simply ignore." That is the contract, and it held through implementation. There is no separate v4 format and no separate v4 file. v3 already reserved an extension directory and an extension payload region in its 1024-byte header, with the rule that a reader rejects only Why this and not a separate
The result: a pure v3 reader opens and extracts a v4 vault unchanged (it walks past the recovery extension), and "v4" is the feature label for "a v3 vault with the Error Correction wrapper enabled", not a version bump. 3. The decision I want your eyes on: where the recovery data livesThis was a stated preference of mine, not a closed agreement between us, so it is the heart of this review. You pictured Error Correction as files "put to the side" (the par2 and Kopia separate-file model), and later as parity "appended to the end of its chunk". I shipped the first cut as an in-container block (the recovery data sealed inside the single Rather than argue one model, here is the full comparison across the dimensions that actually decide it, including the append-per-chunk variant you raised, so the reasoning is on the table and not just the conclusion. 3.1 System comparison
3.2 Failure-mode coverage, stated preciselyOne thing I want to be exact about, because it is easy to oversell Error Correction and you would catch it: a detached parity copy does not make Error Correction a substitute for a second full backup. Parity at, say, 20 percent cannot reconstruct an entire lost medium; if the whole device holding the data dies, the data is gone and a fraction of parity cannot rebuild it. That is what a second copy is for. What the detached copy actually buys is decorrelation: it puts the recovery data on a different medium so that a single localized failure event cannot take out a block and its only recovery copy at the same time. With that framing honest:
3.3 The recommendation, with the reasoningI do not want to pick one model, because the matrix shows they cover different cells and the union covers all of them with one codec. The proposal:
Why Why Why this is cheap to build and not a second engine: the recovery payload is already a self-contained, serializable blob, and the reconstruction path already takes those bytes as an input rather than reading them only from the container. So a detached copy is a placement choice, not a parallel implementation. One codec, one audit pass, your point about audit tractability preserved. Why append-per-chunk is dropped: once you have 4. The metadata locator: now protected for the manifest (implemented)Scrub locates damaged blocks by the per-block
A regression test covers it (corrupt the manifest on disk, the vault still opens, extracts byte-identical, and repair heals the on-disk copy), with a negative control proving a non-Error-Correction vault with the same corruption is fatal, so the rebuild is demonstrably what saves it. The honest remaining limit: this protects the manifest, not the 1024-byte header itself. The header is small, fixed-layout and HMAC-protected, so a header hit currently fails closed at open. Covering the header too is the natural job of the detached copy (the case where the in-file copy is the casualty), and it is on the list below for your review rather than shipped silently. 5. The scheme and its parameters, with the reasoning for eachWhat is built on the embedded side today, and why each parameter is what it is:
6. The commitment, restatedPer what we agreed: this does not get tagged, v3 does not leave Beta, and there is no milestone tag, until you have had a pre-audit review pass on this design and the spec. No deadline pressure from my side; the point of the gate is that the review happens. Anything you flag is a spec bug by default until shown otherwise, same rule as the code. 7. Open to changes and integrationsNothing above is closed except where we explicitly agreed (the wrapper stack, the V4 = V3 + Error Correction contract, the recovery-not-just-generation requirement). I would specifically value your read, and counter-proposals, on:
As always this track carries your name: the wrapper-stack framing, the V4 = V3 + Error Correction contract, the par2 reference, and the recovery-not-just-generation requirement are yours, and the credit stays inline in the spec and in the vault receipt. |
Beta Was this translation helpful? Give feedback.
-
AeroVault v3: stress validation for the Beta to Stable promotionv3 has been the on-disk AeroVault format since Method4,914 real CLI operations across 7 scenario families, run in parallel on the release binary (so the Argon2id 128 MiB KDF runs for real on every open). Every case asserts one of two things: a byte-exact round-trip (SHA-256 of the extracted file equals the original), or a correct rejection (wrong input fails cleanly, never silently). A handful of representative commands are shown below; the battery runs thousands. Scenario families
Results
Representative commands (the battery runs thousands of these)Round-trip integrity, byte-exact across formats, profiles, sizes and content shapes: # v3 / archive profile / 300 KB incompressible
$ aeroftp-cli vault create v.aerovault --vault-version v3 --profile archive
$ aeroftp-cli vault add v.aerovault payload.bin
$ aeroftp-cli vault extract v.aerovault payload.bin out.bin
$ sha256sum payload.bin out.bin # identical
9d399285f16a0bcee0d8420444731240018335bbf0415a949cf2c0797113a909 payload.bin
9d399285f16a0bcee0d8420444731240018335bbf0415a949cf2c0797113a909 out.binTamper detection, a single flipped byte in the ciphertext is caught before any plaintext is returned: $ printf '\x00' | dd of=v.aerovault bs=1 seek=120000 count=1 conv=notrunc
$ aeroftp-cli vault extract v.aerovault payload.bin out.bin
Error: Cipher block hash mismatch for chunk ccb51bfb... # exit 1, rejected before any outputWrong password, fails closed, no plaintext leak: $ AEROFTP_VAULT_PASSWORD="not-the-password" aeroftp-cli vault extract v.aerovault payload.bin out.bin
Error: AES-KW unwrap failed # exit 1, key unwrap fails, no plaintext producedGarbage input, random bytes as a vault never panic the parser: $ head -c 50000 /dev/urandom > junk.aerovault
$ aeroftp-cli vault info junk.aerovault
Error: Failed to read archive: invalid Zip archive: Could not find EOCD # exit 1, clean rejectionConclusion🟢 4,914 / 4,914 cases pass. The integrity guarantee held across 2,500 byte-tamper iterations with zero silent corruption, and 1,500 garbage inputs with zero panics. The one real defect the battery found (the v2 named-extract bug above) is fixed and pinned by a new regression test. Combined with the existing unit suite (full Rust lib suite green) and the v3 audit (CRYPTO-01 chunk-splicing fix shipped in v3), this is a technical green gate. My recommendation: v3 is ready to move from Beta to Stable. As always, nothing here is tagged; flagging it for review first. |
Beta Was this translation helpful? Give feedback.
-
AeroVault v4 (v3 + Error Correction): development follow-up, audit, fixes, and live evidenceStatus at a glance:
Following the Error Correction design I posted here on 8 June, I took the track end-to-end internally so the pre-tag review has something concrete to push on. The point of building it now is exactly to surface technical problems early, before anything is tagged, rather than discover them after a release. Nothing below is tagged or in a release. This is still the review surface; everything is open to change on your read, @EhudKirsh. What is built (recap)v4 is not a new format, it is v3 + an Error-Correction layer, a non-critical extension, so a v3-only reader still opens a v4 vault (it just ignores the parity). The slices, as built:
Audit: final assessmentI ran a full post-implementation audit (four independent review passes: parser/security, Reed-Solomon correctness, sync integration, and code quality/duplication). Headline:
All critical/high/medium items are fixed on the branch, plus a set of low/quality items (dead-code removal, dependency pinning, +9 direct codec tests). Full report lives in the dev appendix. Gate: all green
Live evidence (real CLI, no mocks)Embedded parity: inject damage, detect it, repair it, byte-verify the recovered file: $ aeroftp-cli vault create v.aerovault --error-correction --recovery-level 20
$ aeroftp-cli vault add v.aerovault secret.bin # 300 KB incompressible
$ aeroftp-cli vault scrub v.aerovault --json
{ "checked": 1, "count": 0, "damaged": [], "parity_source": "embedded" }
# corrupt 48 bytes inside the encrypted data section, then scrub again:
$ aeroftp-cli vault scrub v.aerovault --json
{ "checked": 1, "count": 1, "damaged": [ { "id": "e840a885...", "on_disk_len": 300051 } ], "parity_source": "embedded" }
$ aeroftp-cli vault repair v.aerovault --json
{ "repaired": 1, "damaged": 1, "dry_run": false, "parity_source": "embedded" }
$ aeroftp-cli vault extract v.aerovault secret.bin out.bin
$ sha256sum secret.bin out.bin # identical, recovery is bit-exactDetached parity, and the safety property that matters most: a hostile recovery file is rejected, the vault is left untouched, and the genuine parity then repairs the same damage: $ aeroftp-cli vault export-parity v2.aerovault
Wrote recovery file v2.aerovault.rec (12 shards, 300051 bytes protected, 20.1% overhead)
# a random 5 KB ".rec" handed to repair on a damaged vault:
$ aeroftp-cli vault repair v2.aerovault --parity bogus.rec --json
Error: recovery file does not match this vault (exit 1, vault unchanged)
# the real sidecar repairs it:
$ aeroftp-cli vault repair v2.aerovault --parity v2.aerovault.rec --json
{ "repaired": 1, "parity_source": "explicit" }(8/8 live scenarios pass, including Interesting ideas the audit surfacedThese are not committed scope, they are the genuinely novel directions the audit turned up, worth your eyes:
Remaining workDecisions still openThree calls are still open before this can be tagged:
Everything else in the tree above is decided. The tag stays blocked until these are settled; any of them can also move back into the roadmap if that is a better home. |
Beta Was this translation helpful? Give feedback.
-
|
🟢 AeroVault v4 EC follow up: windowed streaming, the size cap is lifted Continuing the large-file thread: the detached How it works, briefly:
Live evidence (real CLI, MEGA, no mocks)
Caps and safeguards
Tests executed
One honest note: the plaintext is fully streamed, but the sidecar itself is still read into memory on the repair path, which is why the default cap is 1 GiB for now. Lifting it further needs a streaming sidecar (parse and fetch parity window by window), which is a separate follow up. Next: a top-level |
Beta Was this translation helpful? Give feedback.
-
|
Good question, and no, the self-healing does not come out of the main file's parity budget. The sidecar has two parts: the parity (the Reed-Solomon shards that actually rebuild your The locator is a few hundred bytes, and it is fixed regardless of file size. Concretely, the redundancy adds about 360 bytes total. On a 1 MB file the whole sidecar is 154,621 bytes at the medium level (15.4% overhead), of which the self-healing redundancy is those ~360 bytes, so roughly 0.2% of the sidecar and 0.04% of the file. Protect a 1 GB file and it is still ~360 bytes, now a rounding error. So self-healing does not reduce how much damage to the main file you can recover. On the "maybe EC should just focus on recovering the original" point: that is exactly the focus, and self-healing serves it. You are right that if you still have a good original you can always regenerate parity, but EC is for the case where you do not. The failure I wanted to close is this one: your So it is not "spend parity to heal the sidecar". It is "spend ~360 fixed bytes so a slightly damaged sidecar is still usable when you need it most". |
Beta Was this translation helpful? Give feedback.
-
AeroVault v4 (v3 + Error Correction): ready to ship, asking for your go-ahead🟢 This is engineering-complete and staged on every surface. Before I tag the release I want your read, @EhudKirsh, since we agreed v4 would go out on your review pass, and your testing and design input shaped most of it. Where it stands: The self-healing Beyond the unit suite there is now a repeatable, seeded stress campaign for the self-healing format, run on the release binary. 2,017 end-to-end cases drive the real
The standout: the app and the standalone The earlier open decisions are settled, the way this thread landed them. There is one unified detached recovery format, Your two recent questions are answered in-thread: the self-healing redundancy costs about 360 fixed bytes and does not touch the main file's parity budget, and the fuzzy-hash idea is better served by the per-shard and per-copy failure counts we already compute (which I am happy to surface as a health readout on verify). Your V3 Beta report on the crate discussion is handled too. Extract all, a first-class add-folder picker, the receipt save dialog, the "Time elapsed" wording, and a pre-flight memory guard so a very large input warns instead of OOMing are all done. Drag-and-drop onto the create screen, the change-mode action, true streaming vault I/O, and the On framing: there is no beta label. The validation here is extensive and the audit is continuous, so refinements land in later releases rather than gating this one. If you are comfortable, I will take that as the go-ahead and tag it. If anything still looks off to you, this is exactly the moment to say so and I will hold. Thank you for the depth you brought to this one. It is a better format because of it. |
Beta Was this translation helpful? Give feedback.
-
After a docs and code review: naming clarity, AeroVault v4, and AeroCrypt ProfilesAn honest note to open. We have just done a thorough pass over our documentation and our code together, and we found a number of things worth tidying, starting with terminology. Clear and consistent naming is something this community has asked for more than once, and it was overdue, so we are doing it in the open. Three things come out of that review. First, we are settling on a clear name for our native client-side encryption overlay: AeroCrypt. The docs have referred to it as AeroFTP-Crypt, and the word overlay had drifted across surfaces, so we are fixing the vocabulary. Second, we are upgrading AeroCrypt from a CLI beta to a first-class component in the GUI. Third, we are adding the new AeroCrypt Profiles on top of it. The rest of this note is the concrete next step that gets us there. To be precise about terms, the earlier request on this thread was for AeroVault v3 plus Error Correction, set out in the two comments above, the ready to go note and the benchmark. That addition, Reed-Solomon parity computed over the v3 ciphertext, is exactly what we mean by v4. The work is built, audited and benchmarked, so we are advancing with it. v4 is the natural and awaited destination this thread has been building toward, not a detour. In plain terms it means a vault can now survive partial corruption: if bytes rot on disk, or a transfer damages part of the container, the Reed-Solomon parity rebuilds the damaged shards and the vault still opens, with verification happening before decryption so a tampered container fails closed. The overhead is a level you pick on the same QR style scale, and the Beta label comes off. The same step consolidates the AeroVault cryptography into one audited engine, and that is what carries us to the rest of the destination. The native AeroCrypt overlay, which has matured through the CLI as a beta, comes to the GUI bound to a saved connection as an AeroCrypt Profile, so any commodity remote becomes a transparent zero knowledge store you browse in the normal dual panel, both sides encrypted and readable only inside AeroFTP. rclone-crypt stays beside it as the interop lane, the way Cryptomator sits beside AeroVault: we support the foreign format and we lead with ours. We will open a dedicated roadmap Discussion to carry that part forward. To keep the two clearly apart, since they are easy to confuse, a quick reminder of the distinction:
Both are built on the same audited crypto core, one codec and one audit pass: only the shape after encryption differs. To be clear, this is not a request for sign off, it is a status update: we are advancing to v4, and gathering remarks from the community along the way. The overlay chapter then begins on top of it. Two points where your input would help most: whether the encrypted scope should default to a subfolder so a profile is never accidentally half encrypted, and whether the platform cipher should be chosen automatically or offered as an explicit toggle. Thoughts from anyone here are welcome, on these or on the terminology cleanup itself.
|
Beta Was this translation helpful? Give feedback.
-
|
There should absolutely be a choice between using Rclone Crypt and AeroCrypt, any time any path is encrypted. Considering that there are risks such as nonce-misuse with Rclone Crypt and the experimental nature of AeroCrypt, I think that both should be opt-in. I was going to write more about this in length in #272, but it's best to write about this now since Crypt for AeroSync seems to be right around the corner. Basically, I'm sitting on a figurative mountain of notes where I write ideas as soon as I come up with them I know that I wrote before that I like the idea of each wrapper being its own profile, but I'm rethinking this. With Rclone, So the order is:
Basically, the first wrapper, whichever it is, shows the files in their original plaintext form when clicking on it or mounting it. I'm guessing that previewing these remote files and their metadata will be in RAM as opposed to temporary files. Whatever AeroFTP does currently when previewing the files that are in cloud drives, as well as what Rclone does in normal and Crypt remotes. To perform Rclone's equivalent of Each set will have its own path. When using Rclone, I personally like to direct Crypt remotes to "Crypt" subfolders. This leaves plaintext sibling items clearly separated from encrypted files and folders, including items that some cloud drives create and refuse to remove. As for the symbol of each overlay badge, I plan to write about it in #272. I was thinking of suggesting even having the ability to have multiple Crypt wrappers in the same set for paranoid defence-in-depth double-encryption, but I think it's best to achieve this with only a single Crypt overlay. So when setting up any overlay, the user will choose its settings, including the number of layers of encryption in Crypt, each having a different algorithm: XSalsa, AES, ChaCha, etc. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.



























Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Anchor for the AeroVault design conversation in Design Threads. The full historical thread lives in the Community Roadmap discussion (the conversation that ran 2026-05-07 to 2026-05-19, with substantial design contribution from @EhudKirsh, credited inline in every AeroVault receipt and in the v3.8.0 release notes).
This post serves two roles at once: a checkpoint of every decision that came out of that conversation, and a starting base for everything that follows. Read it as the shared ground from which the next design questions on AeroVault start, not as a closing summary.
The pipeline at a glance
Each box is a first-class wrapper, not a sub-step buried inside another. Order is non-arbitrary: compression before crypt (so the ratio survives), crypt before ECC (so confidentiality survives parity-byte failures).
Checkpoint: agreed decisions
Cryptography matrix
Position against existing tools:
Where it lives in the codebase
docs/AEROVAULT-V3-SPEC.mdsrc-tauri/src/aerovault/src-tauri/src/vault_telemetry.rs(VaultReport)aeroftp-cli vault {create,add,info,extract}with auto-detection across v1/v2/v3What this thread is for going forward
If a question is small enough to live in the v4+ Wishlist, it belongs there (wishlist Discussion). If it is wishlist-scoped but specifically about AeroVault, drop a link from there back to a post in this thread for the design context. If it is roadmap-scoped (multi-day, architectural), it belongs in the Roadmap discussion; a link from there to a post here is fine when the AeroVault design framing is the focus.
References
docs/AEROVAULT-V3-SPEC.mdBeta Was this translation helpful? Give feedback.
All reactions