════════════════════════════════════════════════════════════════════════ SECURITY MODEL Gnomad Desktop Assistant · docs/SECURITY_MODEL.md ════════════════════════════════════════════════════════════════════════ SECURITY MODEL — GNOMAD DESKTOP ASSISTANT ========================================= Version: 0.1.0-alpha Classification: Internal / portfolio Last updated: June 2026 ──────────────────────────────────────── SCOPE ----- This document describes how Gnomad reduces risk when an LLM can run shell commands and access files. It is not a formal penetration test or certification. In scope: Desktop app on user-controlled machine; cloud (DeepSeek) and local (Ollama) inference; agent tools; keychain storage. Out of scope (alpha): Multi-tenant SaaS, supply-chain signing beyond platform defaults, enterprise MDM deployment guides. ──────────────────────────────────────── THREAT SUMMARY -------------- Threat | Mitigation (alpha) | Residual risk Model suggests destructive shell | privilege heuristics + Sudo Gate | User may approve; heuristics incomplete Model reads sensitive files | Workspace + Path Gate (Standard mode) | YOLO mode expands access by user choice Stolen API key | OS keychain; not logged in UI | Key exfiltration via other malware on host Malicious attachment in chat | User explicitly attaches; sent to model | User social-engineered to attach secrets IPC bypass (modified client) | Commands should re-validate in Rust | Not all paths audited to production bar Prompt injection via clipboard/context | Context labeled; user visibility | Model may over-trust injected text ──────────────────────────────────────── TRUST MODES ----------- Mode | Filesystem | Shell Standard (default) | Read/write/search inside workspace; paths outside require Path Gate | Sudo Gate for flagged commands YOLO! | Broader machine access (user opt-in) | Sudo Gate may still apply for destructive patterns Workspace defaults to $HOME until changed in Settings → Agent access. ──────────────────────────────────────── HUMAN-IN-THE-LOOP GATES ----------------------- Sudo Gate Triggered when check_command_safety marks a command as requiring HITL (e.g. sudo, rm -rf, chmod 777, chained operators). • UI shows reason text • Deny → command not executed • Approve → execution proceeds; macOS/Linux may prompt for administrator credentials Path Gate In Standard mode, filesystem tool calls targeting paths outside the workspace require explicit approval. After Allow once, the app issues a signed path gate token (same HMAC pattern as HITL) bound to the canonical path hash, scope (read / write), nonce, and expiry (~300s). Passing path_approved: true without a token is rejected. Implementation: src-tauri/src/path_token.rs, frontend src/lib/pathToken.ts. Cryptographic approval tokens (Wave B1 — shipped) When check_command_safety requires HITL: 1. After Sudo Gate Approve, the app calls issue_hitl_approval_token (Rust). The backend returns a short-lived HMAC-SHA256 token bound to SHA-256(normalized command), nonce, expiry (~120s), and scope (shell_run or elevated). 2. Signing secret is stored in the OS keychain (hitl-hmac-secret); not exposed to the webview. 3. shell_session_run, agent_execute_tool (shell_run), and execute_elevated_command require a valid token. Passing hitl_approved: true without a token returns safety_blocked (“Unsigned HITL approval is not accepted”). 4. Tokens are single-use (nonce burned in memory after verification). Implementation: src-tauri/src/hitl_token.rs, frontend src/lib/hitlToken.ts. ──────────────────────────────────────── COMMAND SAFETY (SERVER-SIDE) ---------------------------- privilege.rs analyzes command strings before execution: • Splits on ;, &, | • Flags known-dangerous patterns • Returns requires_hitl_approval, requires_admin, danger_reason Shell execution: All agent shell traffic goes through shell_session_run with HITL tokens, validation, and optional sandbox. The legacy execute_shell_command IPC command was removed (no bypass path). ──────────────────────────────────────── SECRETS HANDLING ---------------- Secret | Storage | UI behavior DeepSeek API key | Keychain (+ optional .env in dev) | Never re-displayed after save Ollama URL | Keychain | Editable in settings Chat content | Local app data | Not encrypted at rest (alpha) .env keys show as locked in Settings; user edits file to rotate. ──────────────────────────────────────── AUDIT & OBSERVABILITY --------------------- Agent actions append to: {app_data}/gnomad/agent-audit.jsonl Each line should include timestamp, action type, and outcome (exact schema in agent_audit.rs). Users can inspect this file for accountability. ──────────────────────────────────────── NETWORK EXPOSURE ---------------- Path | Endpoint | Data sent Cloud chat | DeepSeek API | Prompts, tool results, attachments user includes Local chat | User-configured Ollama URL | Same, stays on network path to Ollama Studio link | gnomadstudio.org | Normal HTTPS (user-initiated) No Gnomad Studio backend receives chat content in the alpha architecture. ──────────────────────────────────────── PLATFORM PERMISSIONS -------------------- OS | Permission | Feature macOS | Accessibility | Input automation fallbacks macOS | Automation (System Events) | Window titles macOS | Admin auth | Elevated shell All | Tray / shortcuts | No extra privacy prompt See MACOS_PERMISSIONS.md. ──────────────────────────────────────── HARDENING ROADMAP (POST-ALPHA) ------------------------------ 1. Enforce check_command_safety on every shell invoke path 2. HITL approval token validated in Rust (not UI-only) 3. Tighten CSP for release builds 4. Optional at-rest encryption for chat store 5. Rust unit tests for safety parser edge cases 6. Signed releases + notarization (macOS) ──────────────────────────────────────── RELATED DOCUMENTS ----------------- • ARCHITECTURE.md • PRIVACY.md • QA_CHECKLIST.md — security spot checks Built with ❤️ by Gnomad Studio 🦙 ════════════════════════════════════════════════════════════════════════ Built with ❤️ by Gnomad Studio 🦙 https://gnomadstudio.org ════════════════════════════════════════════════════════════════════════