Security
The vault and encryption at rest, the hash-chained audit log signed in the Secure Enclave, the Derivative Privilege Rule, fail-safe behaviour and the threat model in plain language.
Three layers
| Layer | Mechanism |
|---|---|
| At rest on the device | CryptoVault seals content with AES-256-GCM under the vault key; large assets use EncryptedBundle |
| At rest in iCloud | Sealed bundles travel as CloudKit assets, so Apple stores only ciphertext |
| In transit | TLS to CloudKit around content that is already ciphertext. Between your own devices on the local network, Noise XK over CryptoKit (Curve25519, ChaCha20-Poly1305, SHA-256, HKDF) with forward secrecy, accepted only from devices on your iCloud account or explicitly family-paired |
The vault
- The vault key is derived from your passphrase with Argon2id (m=64 MB, t=3, p=1) through swift-sodium. The scheme tag is stored beside the salt, and vaults created with the older PBKDF2-SHA256 (600,000 iterations) move to Argon2id on their next unlock.
- After setup the key is kept in the Keychain behind biometrics: Face ID or Touch ID unlocks it, with the passphrase as the fallback. The passphrase is never transmitted, and the developer cannot recover it.
- The vault locks after an idle timeout, on demand from the Vault chip, and, if you choose, whenever the app goes to the background with a privileged project open.
RecoverySharescan split the vault key into N shares with a threshold of K (Shamir secret sharing over GF(2^8)), so any K holders together can restore it.
Sealed content
Every privileged project encrypts its content, an invariant the app enforces at start-up. In a privileged project the text of documents, snapshots, branches, research notes, clips and AI task results is sealed under the vault key, or its compartment’s key. Imported research originals are sealed in every project. A wrong passphrase is told apart from real corruption before any content is touched.
Sealed units are bound to their context. For large assets the binding is explicit in the bundle format:
EncryptedBundle
├─ header (32 bytes) "SLEB" magic, format version, reserved, length fields
├─ nonce (12 bytes) AES-GCM nonce
├─ context binding JSON, authenticated as additional data:
│ project ID, scene ID, kind, owner identity hash
├─ ciphertext AES-GCM
└─ tag (16 bytes)
A bundle opened under a different project, document, kind or owner fails authentication, so a file lifted from one place cannot be replayed into another.
Plaintext from a bundle exists only inside PrivilegedProcessingSession.run, which hands the bytes to a closure as TransientPlaintext, logs the start and end to the audit chain, and wipes the buffer with memset_s on every exit path. The rule in code: ciphertext on disk is acceptable, plaintext on disk is a bug.
Compartments
Several passphrases can unlock cryptographically separate workspaces, each with its own salt, derivation scheme and key, and each project belongs to exactly one. This is selective disclosure, not plausible deniability: someone examining the device’s Keychain can count the compartments, but cannot read their labels or contents without the right passphrase.
The audit chain
Every consequential action is appended to the log: AI runs, accesses, exports, copies, pastes into privileged projects, vault unlocks and locks, device dispatches, policy changes, sharing, trash, editing sessions, pairings and every network crossing. Entries hold content hashes, never content.
chainHash(n) = SHA-256( chainHash(n-1) || payload(n) )
signature(n) = ECDSA P-256 over chainHash(n), by a key held in the Secure Enclave
- The signing key is generated inside the Secure Enclave and cannot be extracted.
- Verification recomputes every hash and checks every signature; either failure breaks the chain at that entry. It also compares the head with a pin kept outside the log, in a file and in iCloud key-value storage, so a deleted or truncated history shows, and it checks anchors co-signed across your devices. You can run it yourself.
- The claim is precise: tamper-evident, never tamper-proof. The chain exposes changes by anyone without the device’s private state, and on Secure Enclave hardware the signatures make it non-repudiable. It cannot defend against someone who controls the device.
The Derivative Privilege Rule
Anything derived from privileged content inherits its protection, or is not stored at all.
| Derivative | Treatment |
|---|---|
| Snapshots and branches | Sealed like the document |
| AI task outputs and results | Sealed |
| Research threads in a privileged project | Held in memory only, never written to disk |
| Search history in a privileged project | Sealed to the vault |
| Network crossings | Recorded verbatim in sealed ledger entries; the chain holds only a hash |
| Diagnostic logs and device beacons | Privileged names redacted |
Fail safe
- A locked vault drops writes. A write for an encrypting project that arrives while the vault is locked is dropped, and the earlier sealed content survives. Nothing falls back to plaintext, and locked content shows a “Sealed in Vault” placeholder.
- The forensic guard. Before every unlock,
ForensicGuardrefuses, and logs the refusal, if a debugger is attached, the device appears jailbroken or the code is running in a background task. - The leak check never passes silently. If the semantic check cannot run, the crossing is recorded as warned, not clean.
- Privileged projects stay put. Sharing one is refused, the iOS privacy shield blocks screenshots and screen recording unless you allow them, and every paste into one is logged. PDF export is watermarked and its SHA-256 goes into the chain; password-protected export uses an Argon2id key envelope and requires a strong password.
Threat model
- Someone gets into your iCloud or intercepts sync: sealed content is ciphertext before it reaches CloudKit, which adds its own encryption.
- The developer: no server, no account and no copy of your keys, so nothing to breach, lose or hand over.
- A cloud AI provider: privileged projects never reach one. Elsewhere, it sees only what you send with your own key.
- Anyone logging web searches: protected names never leave, and a guard warns when your searches start to reveal your work. See Research and egress.
- A lost or stolen device: the key sits behind biometrics and your passphrase, and the vault locks itself.
- Out of scope: a device that is already compromised. Someone who controls it while it is unlocked is beyond these defences.