|
1 | 1 | # Security |
2 | 2 |
|
3 | | -## Encryption model |
| 3 | +## Trust model |
4 | 4 |
|
5 | | -siggy is a frontend to signal-cli, which implements the full Signal protocol. |
6 | | -All messages are **end-to-end encrypted in transit** -- siggy never handles |
7 | | -cryptographic keys or plaintext network traffic directly. |
| 5 | +siggy is a **thin TUI layer** over [signal-cli](https://github.com/AsamK/signal-cli). |
| 6 | +It does not implement any cryptographic protocols, manage credentials, or contact |
| 7 | +Signal servers directly. All security-critical operations are delegated to signal-cli, |
| 8 | +which implements the full Signal Protocol. |
8 | 9 |
|
9 | | -However, messages are stored **unencrypted at rest** in a local SQLite database. |
10 | | -This is the same approach used by Signal Desktop and most other messaging clients. |
11 | | -The rationale is that local storage protection is best handled at the OS level |
| 10 | +This means siggy inherits signal-cli's security posture: |
| 11 | + |
| 12 | +- **What signal-cli handles**: key generation, key exchange, message encryption/decryption, |
| 13 | + identity verification, contact and group management, attachment encryption, and all |
| 14 | + network communication with Signal servers. |
| 15 | +- **What siggy handles**: rendering messages in a terminal, storing a local cache of |
| 16 | + conversations in SQLite, and forwarding user actions to signal-cli via JSON-RPC. |
| 17 | + |
| 18 | +siggy never sees plaintext cryptographic keys or raw network traffic. |
| 19 | + |
| 20 | +### Credential storage |
| 21 | + |
| 22 | +Signal credentials (identity keys, session keys, pre-keys) are stored by signal-cli |
| 23 | +in its own data directory (`~/.local/share/signal-cli/` on Linux). **siggy does not |
| 24 | +read, write, or manage these files.** If credential storage security is a concern, |
| 25 | +it should be addressed at the signal-cli level or via OS-level protections (encrypted |
| 26 | +home directory, restrictive file permissions). |
| 27 | + |
| 28 | +## Encryption |
| 29 | + |
| 30 | +### In transit |
| 31 | + |
| 32 | +All messages are end-to-end encrypted using the Signal Protocol, handled entirely |
| 33 | +by signal-cli. siggy communicates with signal-cli over a local stdin/stdout pipe |
| 34 | +using JSON-RPC -- no network sockets are involved. |
| 35 | + |
| 36 | +### At rest |
| 37 | + |
| 38 | +Messages are stored **unencrypted** in a local SQLite database (`siggy.db`). This is |
| 39 | +the same approach used by Signal Desktop and most other messaging clients. The |
| 40 | +rationale is that local storage protection is best handled at the OS level |
12 | 41 | (full-disk encryption, screen lock, file permissions) rather than by individual |
13 | 42 | applications. |
14 | 43 |
|
15 | | -### What is encrypted |
16 | | - |
17 | | -- All messages between your device and Signal servers (Signal Protocol, handled |
18 | | - by signal-cli) |
19 | | -- All media attachments in transit |
| 44 | +The database uses `PRAGMA secure_delete = ON`, which zeroes out deleted content in |
| 45 | +the database file rather than leaving it recoverable in free pages. |
20 | 46 |
|
21 | | -### What is NOT encrypted |
| 47 | +### Files on disk |
22 | 48 |
|
23 | 49 | | File | Contents | Location | |
24 | 50 | |------|----------|----------| |
25 | | -| `siggy.db` | Message history, contacts, groups | Platform data directory | |
| 51 | +| `siggy.db` | Message history, contacts, groups | Platform config directory | |
26 | 52 | | `siggy.db-wal` | Recent uncommitted writes | Same directory | |
27 | 53 | | `config.toml` | Phone number, settings | Platform config directory | |
28 | | -| `siggy-debug.log` | Full message content (when `--debug` enabled) | Current working directory | |
29 | | -| Download directory | Received attachments | `~/signal-downloads` or configured path | |
| 54 | +| `debug.log` | Debug output (opt-in, PII redacted by default) | `~/.cache/siggy/` | |
| 55 | +| Download directory | Received attachments | `~/signal-downloads/` or configured path | |
| 56 | + |
| 57 | +Platform config directories: |
| 58 | +- **Linux / macOS**: `~/.config/siggy/` |
| 59 | +- **Windows**: `%APPDATA%\siggy\` |
| 60 | + |
| 61 | +## Privacy features |
| 62 | + |
| 63 | +### Incognito mode |
| 64 | + |
| 65 | +```sh |
| 66 | +siggy --incognito |
| 67 | +``` |
| 68 | + |
| 69 | +Uses an in-memory database instead of on-disk SQLite. No messages, conversations, |
| 70 | +or read markers are written to disk. When you exit, everything is gone. |
| 71 | + |
| 72 | +### Notification previews |
| 73 | + |
| 74 | +Desktop notification content is configurable via the `notification_preview` setting |
| 75 | +in `/settings`: |
| 76 | + |
| 77 | +| Level | Title | Body | |
| 78 | +|-------|-------|------| |
| 79 | +| `full` (default) | Sender name | Message content | |
| 80 | +| `sender` | Sender name | "New message" | |
| 81 | +| `minimal` | "New message" | *(empty)* | |
| 82 | + |
| 83 | +### Debug logging |
| 84 | + |
| 85 | +Debug logging is **opt-in only** and disabled by default. |
| 86 | + |
| 87 | +- `--debug` -- enables logging with **PII redaction**: phone numbers are masked |
| 88 | + (e.g. `+4***...567`), message bodies are replaced with `[msg: 42 chars]`, and |
| 89 | + contact/group lists show only counts. |
| 90 | +- `--debug-full` -- enables logging with full unredacted output. Only use this |
| 91 | + when you need actual message content for troubleshooting, and delete the log |
| 92 | + file afterwards. |
| 93 | + |
| 94 | +Debug logs are written to `~/.cache/siggy/debug.log` with 10 MB rotation. On |
| 95 | +Unix systems, the log file and directory are created with restrictive permissions |
| 96 | +(0600 / 0700). |
| 97 | + |
| 98 | +### Clipboard |
| 99 | + |
| 100 | +Copied message content is automatically cleared from the system clipboard after |
| 101 | +30 seconds (configurable via `clipboard_clear_seconds` in config). |
30 | 102 |
|
31 | 103 | ## Recommendations |
32 | 104 |
|
33 | 105 | - **Enable full-disk encryption** on your device (BitLocker, LUKS, FileVault). |
34 | 106 | This is the single most effective protection for data at rest. |
35 | | -- **Use `--incognito` mode** when you don't want any messages written to disk. |
36 | | - This uses an in-memory database that is discarded on exit. |
37 | | -- **Avoid `--debug` in production** -- debug logs contain full message content |
38 | | - and are written to the current directory with default file permissions. |
| 107 | +- **Use `--incognito` mode** for sensitive sessions where you don't want any |
| 108 | + messages persisted to disk. |
| 109 | +- **Set `notification_preview = "sender"` or `"minimal"`** if you're concerned |
| 110 | + about notification content being visible on lock screens or in screen recordings. |
39 | 111 | - **Use a screen lock** to prevent physical access to your terminal session. |
40 | | - |
41 | | -## Known limitations |
42 | | - |
43 | | -- **File permissions**: siggy does not currently set restrictive file permissions |
44 | | - on the database, config, or log files. They are created with your system's |
45 | | - default umask. On shared systems, consider restricting permissions manually |
46 | | - (`chmod 600 siggy.db config.toml`). See [#130](https://github.com/johnsideserf/siggy/issues/130). |
47 | | -- **Clipboard**: copied message content remains in the system clipboard until |
48 | | - overwritten. See [#131](https://github.com/johnsideserf/siggy/issues/131). |
49 | | -- **Desktop notifications**: when enabled, notifications may show message |
50 | | - previews visible on lock screens or to screen recording software. See |
51 | | - [#132](https://github.com/johnsideserf/siggy/issues/132). |
| 112 | +- **On shared systems**, restrict file permissions on the config directory |
| 113 | + (`chmod 700 ~/.config/siggy`). |
52 | 114 |
|
53 | 115 | ## Reporting vulnerabilities |
54 | 116 |
|
|
0 commit comments