Docs / Security Architecture
Understand the system and its limits.
9Core owns the canonical vault format, key lifecycle, authenticated commits, Sentinel analysis, and Sync protocol used by the native apps.
9Core is the Rust-based engine responsible for vault storage, operations, history, synchronization, and key lifecycle. It delegates cryptographic primitives to the source-available quantum-crypto library.
Cryptography comparison
Checks indicate publicly documented support. Blank cells mean support was not found or the exact algorithm was not publicly documented.
Offline-first vaults
9Secure does not require an account, cloud vault, subscription, or permanent connection. Managed vaults are portable .9vault files under the configured storage directory. The keyring and vault files remain under your control.
Offline-first does not mean every feature is network-free. Local Sync uses a nearby network, and optional Sentinel HIBP checks contact the Pwned Passwords range service.
Vault and keyring model
Each vault is a flat collection of items with its own random 32-byte Vault Key. There are no folders or tags in the current data model. Attachments are encrypted inside the vault file and supported according to item-type policy.
The Global Keyring is a separate encrypted canonical container. Its concealed records hold Vault Keys and managed relative paths. Vault Keys are random and are not derived from the keyring password.
The user-facing Recovery Key is the encoded 32-byte Keyring Full Key. It can unlock an existing keyring directly. Password unlock derives a wrapping key that unwraps that same Full Key.
Keys and locking
Lock rejects new work, cancels active operations, waits for in-use keys, revokes open child objects, and wipes keyring state. It then attempts to remove tracked plaintext scratch files and reports cleanup failures. Plaintext can remain if deletion fails.
Vault keys and canonical file-encryption keys use zeroizing secure-byte containers. On Unix, 9Core attempts mlock, but failure is tolerated. Windows does not currently call VirtualLock. Decrypted indexes and operation logs use ordinary application memory.
Requested plaintext fields, attachments, Vaultlight actions, and exports cross the native-app boundary. 9Secure cannot truthfully claim that all decrypted session data stays in locked memory.
Key derivation and encryption
9Secure uses NIST's current standardized post-quantum algorithms for key establishment and signatures.
- Argon2id derives only the keyring password-wrapping key. Desktop policy can expose Low through Maximum presets; mobile policy allows Low and Medium.
- HKDF-SHA256 separates metadata, attachment-stream, and commit keys from the Keyring Full Key or Vault Key plus a per-file salt.
- XChaCha20-Poly1305 provides authenticated encryption for metadata and Sync session records.
- HMAC-SHA256 authenticates canonical anchors and footers and confirms Sync session keys.
- ML-KEM, standardized by FIPS 203, establishes post-quantum shared secrets for device pairing and Sync sessions.
- ML-DSA, standardized by FIPS 204, signs ongoing Sync session transcripts for mutual device authentication.
9Core also uses OS randomness, BLAKE3, SHA-1 for HIBP prefixes, and keyed BLAKE3 for pairing-control proofs. Named algorithms define mechanisms, not a blanket security guarantee or a professional cryptographic audit.
Authenticated canonical storage
The canonical format uses a 4096-byte header and append-only generations. Two authenticated anchors select chained footers and authenticated manifests. Payload additional authenticated data binds container, vault, node, and attachment context so records cannot be substituted silently.
A publication appends records and advances an authenticated anchor rather than editing the active generation in place. The previously selected valid generation remains authoritative until a new authenticated anchor is durably published. This supports fail-closed selection around torn publication.
Payload and attachment records are independently authenticated, so damage can be isolated to an affected record when the surrounding authenticated structure remains valid. These controls do not guarantee recovery from every authenticated corruption, missing file, storage failure, or malicious replacement.
VACUUM builds and validates a replacement container before publishing it atomically instead of rewriting the active container in place. History compaction drops older log events according to retention. VACUUM and history compaction are different operations.
Searchable index and concealed payloads
Unlocking decrypts the searchable index, not concealed item payloads or attachment contents. Concealed, TOTP, and passkey credential values live only in independently authenticated per-item payloads and are decrypted on demand. Attachment records are also authenticated independently. Payload access validates an exact match between concealed field IDs and secret values.
The index can contain item titles, types, field labels, non-secret values, and per-field audit cache. The operation log is stored separately from the index and is decrypted only when an operation requires it. Search does not decrypt concealed values.
9Core clears its transient secret-bearing buffers after use where supported. Opening, copying, delivering, exporting, or auditing a requested secret can move plaintext across the native-app boundary into ordinary application memory, where immediate physical wiping cannot be guaranteed.
Passkey credentials
A passkey is a concealed credential attached to a Login, not a separate item type. Its versioned payload contains ES256 key material and account presentation metadata. The private key is not placed in the searchable index, ordinary item fields, or generic plaintext vault export.
9Core validates WebAuthn ceremony inputs and performs credential operations. Native credential-provider extensions own browser and app integration, request transport, relying-party scoping, user presence, user verification, and interface. System integration is available through compatible Windows, macOS, iOS, and Android credential-provider APIs.
Passkeys synchronize as independently stamped concealed Login fields. A received credential is marked backed up only after an authenticated Sync import commits durably. Failed or cancelled transfers do not change that state. Passkey import from external password-manager exports is not supported.
Authenticator secrets and codes
An Authenticator setup value is a concealed TOTP field inside the Login payload. It is not stored in the searchable index. It synchronizes with the Login through the same authenticated field and payload model as other concealed values.
9Core validates the Base32 secret or otpauth://totp URI and computes the current code locally on demand. Code generation starts no persistent core timer, writes no vault state, and creates no history event. Native apps request a new snapshot at the period boundary and own display, clipboard, and input delivery.
A generated code is transient but becomes plaintext in native app memory and may enter the clipboard when copied. An accurate device clock is required. Storing the password and TOTP secret together protects both at rest, but it does not preserve factor separation against compromise of the unlocked device or vault.
SSH command execution
SSH Key items store public keys, concealed private keys, concealed passphrases, notes, and saved commands. Command titles and command text are ordinary searchable text fields. 9Core stores and synchronizes them but never executes commands or installs keys.
The Windows and macOS hosts can execute a saved command through the user's desktop shell and supply the concealed passphrase through a temporary SSH askpass helper. The command is not restricted to SSH syntax. Shell operators and non-SSH programs can run with the user's permissions. Review every command and trust its source before running it. The stored private key is not automatically written to disk or added to an SSH agent.
Device authentication and app boundaries
Operating-system device authentication can protect a locally saved unlock credential. It is a convenience mechanism. The keyring password and Recovery Key remain the independent unlock paths.
The native app owns inactivity timers, suspend and background handling, clipboard delivery, file pickers, permissions, local networking, and plaintext presentation. 9Core cannot enforce app behavior after plaintext crosses the native-app boundary.
Windows uses Windows Hello and has no 9Core VirtualLock integration. Lock clears 9Secure-owned clipboard content when it still owns the entry.
macOS can use Touch ID or device-password authentication. Vaultlight Accessibility permission is required for global Escape fallback, Paste, and Type Out.
iOS can use Face ID, Touch ID, or device passcode. When backgrounded, 9Secure attempts to remove tracked decrypted attachment scratch files, reports cleanup failures, and overlays a privacy screen while inactive. Plaintext can remain if deletion fails.
Authenticated local Sync
Pairing binds the combined device public keys through the ML-KEM and displayed-number transcript plus bilateral control proofs. Ongoing Sync sessions use ML-DSA transcript signatures, ML-KEM shared material, HKDF-derived directional XChaCha keys and nonces, HMAC key confirmation, exact sequence numbers, and authenticated record headers.
Replay, sequence gaps, reflection, scope substitution, and record tampering are terminal errors. A first-time vault transfer carries its Vault Key only inside the authenticated encrypted session. Per-vault subscriptions limit which paired peers receive which vaults.
9Core runs Sync over a connection supplied by the native app. Discovery, sockets, firewall behavior, and connection lifecycle belong to that app. Current apps document local-network Sync only. No hosted relay or internet Sync service is claimed.
History, conflicts, and restore limits
Changes carry time-ordered event IDs and logical device stamps. Deletes, removed fields, and removed attachments use tombstones. Current-state Sync reconciles stamped values deterministically, while history merges separately by operation ID.
The app Log is read-only even though it can classify Restored events. 9Core has partial inverse support for a limited set of operations, but the native apps do not expose general undo, point-in-time restore, or restore-anything behavior. Compaction can permanently drop old events and payload material.
An equal-stamp, unequal-value conflict fails closed. Edit and save the field on one device to create a new stamp, then Sync again.
Recovery, backups, exports, and archive
A Recovery Key unlocks an existing keyring. A Vault Key unlocks only its matching vault. Neither can recreate missing files. Losing the keyring and its backup loses its inventory, and losing every copy of a Vault Key makes that vault unrecoverable.
9Secure does not create automatic or versioned backups. Sync is not a backup because valid changes and deletions can propagate.
Select Lock first, copy the encrypted .9vault files plus the encrypted keyring, then test the copies. On Windows, closing the window may only hide or minimize 9Secure; use Lock or fully quit from the system tray.
iOS can export encrypted .9vault copies, but the current app has no non-destructive active-keyring backup action. Archive Keyring removes the active keyring and must not be treated as a routine backup.
Archive Keyring is destructive
Archive Keyring prepares and writes an encrypted .9keyring archive, confirms that the active source still matches the prepared buffer, then deletes the active keyring. 9Core does not reopen or authenticate the written destination. After deletion, the native app attempts to remove the saved device-unlock credential and returns to setup or locked state. It is an archive or migration operation, not a verified backup.
Plaintext exports
Export Plaintext Keys writes every Vault Key in plaintext. Anyone with that file can decrypt the matching vaults. Secure deletion cannot be guaranteed on modern filesystems, backups, snapshots, restore points, or synced folders.
Export Vault exports plaintext vault.md plus an attachments folder when needed. Choose a protected destination and remove every copy when finished.
Export Vault exports the original encrypted .9vault bytes. This differs from the Windows and macOS plaintext Markdown bundle.
Trust and threat boundaries
- Protected against: unauthenticated canonical record changes, wrong keys, many torn publications, Sync record tampering, replay, reflection, and untrusted peers that cannot complete pairing authentication.
- You must trust: the installed 9Secure and 9Core binaries, their cryptographic dependencies, the operating system, device authentication, native app interface, storage, and input and clipboard path while secrets are in use.
- Not protected against: malware or an attacker controlling an unlocked device, screen or keyboard capture, a malicious accessibility tool, copied plaintext exports, compromised clipboard managers, traffic analysis, or someone with both the encrypted files and their keys.
- Not recovery guarantees: append-only commits, anchors, and VACUUM do not provide universal corruption recovery, automatic backups, or general undo.
- Not current features: tags, hosted relay Sync, cloud recovery, passkey import from external password-manager exports, and automatic backup management are not part of the documented production behavior.
Post-quantum ML-KEM and ML-DSA address key establishment and signatures. They do not remove endpoint, implementation, password, metadata, backup, or operational risk.