Architecture¶
paranoid-passwd now uses a Cargo workspace:
crates/paranoid-corecrates/paranoid-auditcrates/paranoid-opscrates/paranoid-sealcrates/paranoid-clicrates/paranoid-guicrates/paranoid-vault
The shared crate split is deliberate: security-sensitive generation and vault mechanics stay in the
core and vault crates, operation orchestration starts in paranoid-ops, seal lifecycle posture
starts in paranoid-seal, and structured evidence starts in paranoid-audit instead of UI-local
logging.
Core¶
paranoid-core is the single source of truth for:
charset resolution and validation
OpenSSL-backed CSPRNG access
rejection sampling
constrained generation
SHA-256 hashing
chi-squared distribution checks via
statrsserial correlation
collision counting
pattern detection
compliance evaluation
The old raw-memory WASM result struct is gone. Application surfaces now pass typed Rust data structures between layers. Future Slint WASM/mobile targets must keep that typed Rust boundary and cannot revive the retired JavaScript browser app.
The shared report model is split between:
GeneratedPasswordfor per-password counts, pattern checks, hashes, and framework verdictsAuditSummaryfor batch-level chi-squared, serial correlation, collision, and entropy reporting
CLI and TUI¶
paranoid-passwd is the primary user binary.
On an interactive TTY with no mode-forcing or operational flags, it launches the TUI.
In automation or with
--cli, it keeps the scriptable stdout/stderr contract.That launch policy is treated as the standard product contract: default TUI, explicit or implied headless CLI when operational flags are present, dedicated GUI app when the GUI surface is launched.
The TUI uses
ratatuipluscrosstermto keep the current three-step product flow.paranoid-passwd vaultfollows the same contract: interactive TTY with no vault subcommand opens the native vault TUI, explicit subcommands stay headless.The
vaultnamespace adds encrypted local retention without changing the generator root behavior.Vault filtering is standardized across modes:
vault list --query ... --kind ... --folder ... --tag ..., the vault TUI/filter editor, and the GUI vault filter controls all call the same typed decrypted local summary filter inparanoid-vault, including kind, folder, and tag metadata stored inside encrypted payloads.Duplicate-password detection for
Loginitems is also standardized at the vault layer and surfaced consistently in CLI, TUI, and GUI views without adding new persisted state.The vault TUI and GUI now both include native keyslot inspection, recovery-posture reporting, mnemonic/device-bound/certificate enrollment flows, in-place mnemonic rotation, certificate rewrap, non-destructive keyslot relabeling, password recovery-secret rotation, selected non-recovery slot removal, and device-slot rebind operations. Certificate-backed slots now persist public lifecycle metadata such as subject and validity window so CLI, TUI, and GUI can surface rotation pressure without shelling out to external tooling. Both interactive surfaces support direct native unlock input for recovery-secret, mnemonic, device-slot, and certificate-backed access when shell env setup is unavailable, and all three native surfaces expose the same encrypted backup and selective transfer export/import model. CLI remains the headless administration surface for scripting and automation, not the sole vault-exchange surface.
Certificate lifecycle admin is now standardized before mutation as well as after: CLI can preview a PEM with
inspect-certificate, inspect a persisted slot withinspect-keyslot, and the TUI/GUI certificate enrollment and rewrap forms parse the candidate PEM and show public metadata before changing vault state.Certificate lifecycle interpretation is also centralized now:
paranoid-vaultcomputes shared health warnings for not-yet-valid, expired, or near-expiry certificate slots, and the CLI/TUI/GUI consume that same assessment instead of inventing UI-local rules.Backup administration is standardized across surfaces as well: the engine now exposes a typed backup summary over item-kind counts, keyslot posture, and format compatibility; CLI exposes that via
vault inspect-backup, and the TUI/GUI import-export screens render the same summary before restore. Separate item-level transfer packages use the same engine model and are now available across CLI, TUI, and GUI, while still remaining distinct from full-vault restore flows because they carry selected decrypted item payloads under fresh unwrap material instead of the source vault header and ciphertext rows.Keyslot removal policy is now standardized across surfaces:
VaultHeader::assess_keyslot_removal()computes the same before/after posture and warning set for CLI, TUI, and GUI; headless removal requires--forcefor posture-downgrading removals, while TUI and GUI arm a native confirmation step before proceeding.Native interactive surfaces share a small session-hardening layer from
paranoid-vault: copied secrets are cleared from the clipboard after 30 seconds if unchanged, and unlocked vault views auto-lock after 5 minutes of inactivity while clearing cached decrypted state.
Ops, Audit, and Seal Lifecycle¶
The ops/audit layer is now a typed local control plane, not UI-local logging. CLI --json runs
through paranoid-ops, returns a stable operation report, and carries paranoid-audit events with
an operation id shared by every event in the report. Current operation ids are process-local
correlation identifiers, not authentication tokens or cryptographic nonces.
paranoid-ops owns:
command envelopes with request ids, actor context, session surface, transport, profile, and command identity
authenticated mTLS transport evidence for commands that cross a process boundary, including non-secret peer identity, certificate fingerprint, channel-binding, and warning evidence
an OpenSSL-backed mTLS JSONL command transport that accepts typed command envelopes across a process boundary, replaces client-supplied transport claims with server-observed peer-certificate evidence, and returns the same typed command trace used by local adapters
an explicit
allow,challenge, anddenypolicy decision modelfederal-ready startup evidence over build id, platform, audit schema, configured audit-sink health, and OpenSSL provider evidence
a fail-closed federal policy that requires an audit sink and confirmed approved-provider evidence before security-relevant operations can run
request/response audit event helpers so every command that reaches policy evaluation can be paired by request id
paranoid-seal owns:
a vault seal state machine covering
sealed,challenge_pending,unsealed,idle_lock_pending,sealed_after_timeout, andrecovery_requirednon-secret seal provider evidence for password recovery, mnemonic recovery, device-bound, certificate-wrapped, and future external auto-unseal paths
a seal posture report that distinguishes configured auto-unseal from confirmed provider availability
This is challenge/response in the security sense, not prompt-engineering in the LLM sense. Sensitive operations declare the command, surface, profile, and preconditions; policy returns a typed challenge when fresh proof is required, or a typed denial when controls are missing.
paranoid-audit owns:
structured audit events with per-operation sequence ids
append-only JSONL file sinks through
--audit-jsonlJSONL sink health evidence covering configured, writable, unavailable, and not-configured states
external audit-device probe boundaries, including TCP reachability evidence that remains
unverifiedand an mTLS JSONL write-ack probe that requires a matching challenge beforereadystable typed ops trace fixtures for CLI, TUI, GUI, and mTLS process-boundary vault operation automation
strict redaction markers for sensitive attributes
SHA-256 hash-chain evidence generated through the
paranoid-coreOpenSSL-backed hash pathfail-closed integration when a required audit sink is unavailable
Audit events are evidence metadata only. They must not contain plaintext passwords, recovery phrases, private keys, or unwrapped vault material. Generated passwords remain in the typed generation report and are not copied into audit messages or attributes.
The CLI exposes the first automation surface:
--audit-jsonl PATHappends policy and operation audit events to a JSONL sink after the path passes a local writable health check--require-audit-sinkfails closed unless the sink is writable--profile federal-readyand--federal-readyenforce the federal-ready startup policy--federal-evidenceemits assessor-readable startup evidence as JSONvault --audit-jsonl PATH <subcommand>wraps headless vault subcommands in typed ops request/response audit eventsvault seal-statusreports the local vault seal posture without decrypting item payloadsvault seal-status --probe-providersperforms explicit provider availability checks before marking an auto-unseal provider available; device-bound probes verify the secure-storage unwrap material against the keyslot check blob without decrypting vault itemsvault federal-evidenceemits the same federal startup evidence from the vault namespace
The native TUI and GUI now evaluate local vault actions through the same typed ops protocol before
calling paranoid-vault, and their tests record non-secret request/response policy events for read,
mutate, keyslot, and export flows. TUI launches inherit vault --audit-jsonl / --require-audit-sink
policy, and the GUI exposes the same durable local JSONL sink controls for deterministic automation.
The mTLS process-boundary path now has a live JSONL command transport in paranoid-ops; the server
side evaluates the received envelope only after binding the session to the observed mTLS peer
certificate, not to client-asserted evidence. The seal-provider health path now distinguishes
metadata-only posture from explicit provider probes: configured device-bound slots remain
configured until a probe verifies secure-storage availability, and only then can posture claim
auto_unseal_available=true. The remaining implementation work is broader PTY coverage over those
same command envelopes and release-grade packaging evidence.
The seal model stays local-first but borrows the operational shape of Vault: a sealed vault can read metadata needed to decide how to unlock, but it cannot decrypt stored item payloads. Auto-unseal providers are convenience paths for retrieving unwrap material under policy; they do not remove the need for recovery coverage. If a seal provider is rotated, disabled, or becomes unavailable, the ops and seal layers should expose that as posture and state, and the vault layer should only perform rewraps through typed, audited operations. The ops policy context now accepts non-secret seal posture evidence: federal certificate unlock requires that posture to be present, and device-bound unlock fails closed without seal posture evidence or confirmed auto-unseal availability.
This split keeps the trust boundaries narrow:
paranoid-coreremains responsible for generation, hashing, audit math, and compliance checks.paranoid-vaultremains responsible for encrypted storage, keyslots, and unwrap/rewrap mechanics.paranoid-opsbecomes the command, policy, and automation boundary.paranoid-sealbecomes the vault seal-state and auto-unseal posture boundary.paranoid-auditbecomes the durable security-event boundary.CLI, TUI, and GUI become presentation adapters over the shared protocol.
This same split is the path toward a federal-ready profile. FedRAMP High, GovCloud, and DoD IL5 customers need evidence and enforceable operating modes, not UI-local logging. The ops/audit crates should therefore emit stable JSON/JSONL evidence, support SIEM ingestion, report external audit-device posture without overstating health, prove required audit sinks are healthy, separate TCP reachability from durable audit ingestion, and expose FIPS-provider and policy-profile evidence without claiming authorization for an unassessed boundary. See Federal Readiness.
GUI¶
paranoid-passwd-gui is the dedicated GUI surface. The project is now Slint-native under the GPLv3
licensing path, and it shares the same core request/result model, native vault Login,
SecureNote, Card, and Identity CRUD/filter flows plus
folder-plus-tag organization, login password-history visibility, duplicate-password visibility,
native keyslot management, recovery-posture reporting, direct native unlock, encrypted backup
export/import, clipboard auto-clear, and vault idle auto-lock.
The checked-in Slint surface lives under crates/paranoid-gui/ui/ and is compiled by the GUI crate
build script. Desktop remains the primary release target. Android and WASM are now explicit local
build-chain targets through make configure, make test-gui-android-check, and
make test-gui-wasm-check. Android compile-checks through the configured NDK with the native
paranoid-core and paranoid-vault crates linked. WASM compile-checks a gated non-secret Slint
surface that does not link the native vault or generator crates; storage, crypto, release packaging,
and runtime validation for wasm32-unknown-unknown remain separate threat-model work and cannot
revive JavaScript secret-handling logic or the retired DOM app.
crates/paranoid-gui uses a crate-local unsafe_code = "deny" lint instead of the workspace
forbid because Slint’s generated Rust and Rust 2024 platform ABI export attributes need to lower
that lint internally. The handwritten GUI sources are still checked by
scripts/hallucination_check.sh; only exact #[unsafe(no_mangle)] ABI attributes are allowed
there, and all security-sensitive crates retain the workspace forbid policy.
Local Vault¶
paranoid-vault is the encrypted local vault crate boundary.
SQLite is the explicit vault file format, not a temporary backend choice.
The vault stays local-device only and uses rollback-journal SQLite rather than a persistent WAL profile.
A random master key encrypts vault items.
Keyslots unwrap that master key:
password_recoveryis the current recovery pathmnemonic_recoveryis the current wallet-style recovery phrase pathcertificate_wrappedis the current certificate-based unwrap pathdevice_boundis the current passwordless local-unlock path via platform secure storage
Argon2id derives the recovery KEK.
BIP39 encodes a 24-word recovery phrase for mnemonic recovery slots.
OpenSSL-backed AES-256-GCM encrypts item payloads.
OpenSSL CMS envelope encryption wraps the master key for certificate slots.
Device-bound slots store the unwrap secret in OS secure storage and keep only verification metadata in SQLite.
Keyslot lifecycle operations are now part of the native product surface: mnemonic recovery slots can be rotated in place to a replacement phrase without changing the slot id, certificate-wrapped slots can be rewrapped in place to a replacement recipient certificate, the native TUI/GUI rewrap flows can optionally update the active certificate key path and passphrase when the live session is using that slot, keyslot labels can be updated in place, the password recovery slot can be rewrapped in place, non-recovery slots can be removed, device-bound slots can be rebound to a fresh secure-storage account, and the unlock layer keeps explicit slot selection stable when multiple device or mnemonic slots exist.
VaultHeader::recovery_posture()gives every surface the same policy view over whether the vault currently has recovery coverage, certificate coverage, and the recommended combination of both.VaultHeader::recovery_recommendations()andVaultHeader::assess_keyslot_removal()extend that into actionable policy: the product can now tell the operator what coverage is still missing and when a keyslot removal would weaken the vault’s access posture.The current item model supports
Login,SecureNote,Card, andIdentityentries, CRUD operations, folder-plus-tag metadata, encrypted password history forLoginitems, duplicate-password detection across unlockedLoginitems, generate-and-store flows forLoginthat can either create a new item or rotate an existing login in place, encrypted backup export/import, and native vault TUI/GUI surfaces with unlocked local filtering.VaultBackupPackageremains the portable encrypted backup format, andVaultBackupSummaryis the read-only inspection model used to preview recovery packages before import.VaultTransferPackageis now the separate portable encrypted item-exchange format. It carries selected decrypted item payloads under a fresh AES-256-GCM data key, and that data key can be wrapped by a recovery secret, a recipient certificate, or both. Import happens into an already unlocked local vault and can remap conflicting ids safely instead of overwriting by default.
See Vault Format for the storage-engine decision and on-disk layout.
Public Website¶
The public website is documentation only. GitHub Pages publishes the repository docs/ tree, including:
installation instructions
TUI walkthrough
architecture and testing notes
release verification guidance
generated Rust API docs via
sphinx-rust
Release Path¶
Release packaging is driven by checked-in scripts instead of workflow-only shell:
scripts/build_release_artifact.shscripts/smoke_test_release_artifact.shscripts/release_validate.sh
Linux release builds run inside the repository-owned builder action. Native macOS and Windows archives use the same repo-owned packaging and smoke-test scripts on platform runners. Linux now also emits .deb packages through the same checked-in packaging scripts instead of a separate external packaging pipeline.
The release surface now includes both:
paranoid-passwdfor CLI/TUI and headless automationparanoid-passwd-guifor the dedicated desktop app surface
install.sh and package-manager publication remain intentionally scoped to the CLI/TUI artifact.