Skip to content

Security

Terminality's security model treats the React/React Native layers as untrusted presentation clients. Secrets never cross the Rust–JavaScript boundary.

Trust Boundaries

┌─ Untrusted ─────────────────────┐  ┌─ Trusted (Rust) ────────────┐
│ React / React Native            │  │                             │
│ - Renders UI from ViewModels    │  │ - Cryptography               │
│ - Invokes typed Commands        │  │ - Credential resolution      │
│ - Never sees private keys       │  │ - Host-key decisions         │
│ - Never sees passwords          │  │ - File operations            │
│ - Never constructs shell exec   │  │ - PTY / ConPTY management    │
└─────────────────────────────────┘  └─────────────────────────────┘
  • Tauri WebView: packaged assets only, restrictive CSP, core:default capability only. Filesystem and shell plugins intentionally absent.
  • Custom Tauri commands expose domain operations, not arbitrary paths or process execution.
  • The public Session binding has no openLocal(program, arguments) escape hatch.

Vault Cryptography

Record Encryption (at rest)

  • Algorithm: XChaCha20-Poly1305
  • Nonce: random 24-byte per record
  • AAD: record ID, record type, schema version, revision, tombstone
  • Zeroization: plaintext buffers and derived keys are zeroized after use

Export Archives (.sztvault)

  • KDF: Argon2id — 64 MiB memory, 3 passes, 4 lanes → 32-byte key
  • Salt: random 16-byte
  • Header: versioned, AEAD-authenticated
  • Import: rejects unsupported parameters before derivation (prevents DoS via attacker-selected KDF costs)

Key Storage

  • Desktop: random 256-bit device key → macOS Keychain / Windows Credential Manager / Linux Secret Service
  • Debug builds: isolated development/ app-data directory with local key — never touches OS credential store
  • Mobile: iOS Keychain / Android Keystore (required native work, release blocker)

Repository

One shared EncryptedVaultRepository (Arc-injected) for Hosts, QCS history, Settings, and Quick Commands. Only authenticated encrypted envelopes touch SQLite. Schema migration is monotonic — future versions are rejected, never downgraded.

Host & Credential Protections

  • Host profiles encrypt metadata (hostnames, tags, directories, RDP options) together with the opaque credential reference.
  • Passwords, private-key bytes, and passphrases are never fields of HostProfile, CreateHostArgs, or UpdateHostArgs.
  • RDP passwords go through a dedicated command: zeroizing buffer, seal as separate Credential record, return opaque reference only.
  • SSH Hosts are shared by SSH/SFTP/Omini. FTP and RDP are independent families — cannot borrow another family's endpoint or credentials.

Terminal Protections

ProtectionMechanism
No silent clipboard writeOSC 52 disabled
No clickable links (yet)Link addon not installed; external-link confirmation required before enabling
Multi-line pasteConfirmation dialog in terminal surface
Command Composer64 KiB cap, explicit per-tab confirmation, running sessions only, per-Pane results
Quick CommandsFill draft only — never execute, never persist draft
Output boundedQueue depth 64 × 8 KiB, backpressure on PTY reader
Close guardUnix: foreground process group check. Windows: conservative live-session confirmation
tmux safetyParsed $id + generation; rejects restarted-server reuse; names length/character validated

RDP Protections

  • Independent Host family — cannot borrow SSH/SFTP/FTP credentials.
  • NLA default; legacy TLS requires explicit opt-in.
  • Certificate pinning: first-use SHA-256 leaf review → pin → changed leaf re-triggers review.
  • Separate target and gateway credentials with different opaque IDs.
  • Clipboard/drive channels not compiled.
  • Connection generations reject stale completions, input, and frames.

Local File Protections

See Local Files for the complete safety design: descriptor-relative traversal, generation-scoped references, triple-verified identity, trash-only deletion, bounded batches.

Platform Discovery

  • Runtime-only, never persisted, never imported as Hosts.
  • Requested only when QCS opens — not at startup.
  • Platform tools invoked as executable + fixed argument vector, never through a shell string.
  • Hard deadlines, bounded stdout/stderr, machine-count limit.
  • Discovered actions disabled until native endpoint resolver and production backend are connected.

Logging & Telemetry

  • No telemetry or crash upload configured.
  • New diagnostics must be opt-in.
  • Must never include: commands, terminal output, paths, hostnames, secrets, raw vault errors.
  • DTO logging from session, file, host, and vault commands is avoided.

Dependency Policy

  • Commercially compatible licenses only (MIT, Apache-2.0, BSD, ISC, etc.) — enforced by cargo deny.
  • CI blocks high/critical npm advisories.
  • Bundled fonts: audited, pinned, content-addressed — never downloaded at runtime. Attribution recorded in third-party notices.

Terminality — Connect Everycorner