The security model, in full
What protects your vault, what it protects against, and the rules the app holds to even when they make it less convenient.
What Custodia is for
Custodia protects data at rest on a device you physically hold. Someone with your locked Mac or iPhone — a thief, a repair shop, a border officer, a housemate — cannot read a locked vault without the master password.
It is not a defense against a compromised device. Malware already running as you, a keylogger, or someone watching an unlocked screen can see whatever you can see. No vault can fix that, and one that claimed to would be lying.
macOS: one encrypted volume
The vault is an AES-256 encrypted sparsebundle created and mounted through Apple's own
hdiutil. Custodia does not implement encryption; it drives the same disk-image
machinery macOS uses for encrypted volumes.
-
The vault lives at
~/Library/Application Support/Custodia/vault.sparsebundle, sparse, with a 2 TB ceiling. It occupies only what you have actually put in it. -
Unlocked, it mounts at
/Volumes/CustodiaVaultand is kept out of the Finder sidebar. Locked, the volume is unmounted and the blob is all that remains. -
The master password is handed to
hdiutilon standard input. It never appears in an argument list, where any user on the machine could read it out of the process table, and it is never written to disk. - The vault directory is excluded from Time Machine, so backups cannot silently keep a second copy outside your control.
-
A vault backup is a compressed, read-only AES-256
.dmgbuilt straight from the mounted volume, with no plaintext staged on disk along the way. It opens in Finder with the same master password, on any Mac, with Custodia nowhere in sight.
iOS: one key per item
An iPhone cannot mount a disk image, so the iOS vault encrypts each item separately with CryptoKit. The result is a key hierarchy rather than a single volume key.
- Your password goes through PBKDF2-HMAC-SHA256 against a 32-byte random salt. The iteration count is calibrated on first run to take roughly half a second on your particular device, and never drops below 600,000.
- The derived key wraps a vault master key: 256 bits of randomness that never leaves memory unwrapped. The password protects this key and nothing else.
- The vault master key wraps the manifest key and one random file key per item. Because no bulk data is ever encrypted under the master key directly, deleting an item is simply dropping its key.
- Item bytes are encrypted as 1 MiB AES-256-GCM chunks. Each chunk's nonce combines eight random per-item bytes with the chunk's position, and each chunk is authenticated against the item's identity, its index, and whether it is the last one.
That last detail is what stops a tampered file from being quietly accepted. Reordering chunks, substituting a chunk from another item, truncating the final chunk, or flipping a single bit all fail loudly — and the test suite asserts each of those failures individually, so they cannot regress unnoticed.
No password is stored, not even hashed
Nothing on the device records your password or a hash of it. The authentication tag on the wrapped vault master key is the verifier: the wrong password fails to unwrap, and that failure is the entire check.
Face ID is a shortcut, not a second door
Enabling Face ID stores one item in the Keychain — a wrap of the vault master key, marked so it never syncs to iCloud and is invalidated the moment a face is re-enrolled or the passcode changes. When that happens Custodia discards it and asks for the password again. It is the only thing the app ever puts in the Keychain.
Sharing into a locked vault
The share extension can accept a file while the vault is locked, which means it must encrypt something it cannot read back. It seals each new file key to the vault's public key and leaves the ciphertext waiting; the app absorbs it on the next unlock. The extension never holds the vault master key, so compromising it yields nothing that is already in the vault.
Rules the app holds to
- No recovery path. Not a reset, not an escrowed key, not a support process that can let you back in. Every one of those is also a way in for someone else.
- No network, on either platform. Neither app requests a network entitlement, so the capability is absent rather than merely unused.
- No custom cryptography and no third-party packages. Apple's primitives only, and nothing else in the dependency list to audit or to trust.
- No decoy vaults or fake crashes. Custodia can wear a plain window title and a neutral icon so it doesn't announce itself on a shared screen. It will not pretend to be broken or show a fake vault full of decoy files — under real duress those tricks tend to make things worse, not better.
- Plaintext stays inside the vault. On macOS nothing decrypted is written outside the mounted volume. On iOS previews live in a protected scratch directory that is wiped on lock, on backgrounding, and on launch.
Where the edges are
These are the limits worth knowing before you rely on it, not after.
- Secure deletion is best effort. SSD wear leveling can leave remnants of overwritten data that no application can reach. Run FileVault on the source disk if that matters to you.
- A vaulted app leaves traces. Vaulting removes the application bundle from
disk. Preferences, caches and state already written to
~/Librarystay behind. - Auto-lock measures activity in the app. Working in the mounted vault through Finder does not reset the idle timer.
- A backup is a second copy. It carries the same encryption and the same no-recovery rule, but it lives wherever you put it. Choose that place deliberately.
Reporting a vulnerability
The address for security reports is being set up and will be published here before Custodia reaches the App Store. Reports get a reply rather than silence, and the only thing asked in return is a reasonable window before you publish.