Security Model
Also available: Markdown · Plain text
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:
- After Sudo Gate Approve, the app calls
issue_hitl_approval_token(Rust). The backend returns a short-lived HMAC-SHA256 token bound toSHA-256(normalized command), nonce, expiry (~120s), and scope (shell_runorelevated). - Signing secret is stored in the OS keychain (
hitl-hmac-secret); not exposed to the webview. shell_session_run,agent_execute_tool(shell_run), andexecute_elevated_commandrequire a valid token. Passinghitl_approved: truewithout a token returnssafety_blocked(“Unsigned HITL approval is not accepted”).- 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)
- Enforce
check_command_safetyon every shell invoke path - HITL approval token validated in Rust (not UI-only)
- Tighten CSP for release builds
- Optional at-rest encryption for chat store
- Rust unit tests for safety parser edge cases
- Signed releases + notarization (macOS)
Related documents
ARCHITECTURE.mdPRIVACY.mdQA_CHECKLIST.md— security spot checks
Built with ❤️ by Gnomad Studio 🦙