--- title: Security description: What TabMind stores, what leaves your device, and how encryption + sync providers protect your index. sidebar_position: 6 ---

Security

TabMind's promise is simple: your tabs are yours. This page spells out exactly what data lives where, what crosses the wire, and which guarantees hold even if a sync provider is breached.

> The 30-second version. Tabs, page text, and extraction results stay > in a local SQLite database on each device. If you enable sync, the > encrypted index blob uploads to the provider you chose — and you > choose. LLM extraction, if enabled, sends only the active tab's URL > + extracted text to the provider you configured. We have no servers.

Data flow at a glance

`text ┌─────────────────────────────────────────────┐ │ YOUR DEVICES │ │ │ Browser ──▶ │ TabMind ──▶ Local SQLite (sql.js) │ tab events │ │ ▲ │ │ │ │ read/write │ │ ▼ │ │ │ Extraction ─────┘ │ │ │ │ │ │ (only if you enabled an LLM provider) │ │ ▼ │ │ Outbound HTTPS to chosen provider │ └─────────────────────────────────────────────┘ │ │ encrypted blob (sync) │ OR URL+text (LLM, opt-in) ▼ ┌─────────────────────────────────────────────┐ │ Sync provider (WebDAV / S3 / Drive / …) │ │ — sees opaque ciphertext only │ │ │ │ LLM provider (OpenAI / Anthropic / Ollama)│ │ — sees URL + page text you extracted │ └─────────────────────────────────────────────┘ `

There is no TabMind-operated server in this diagram. The only third parties involved are the ones you configure.

What we store locally

The local index is a single SQLite file. The full schema is in [API reference → Storage schema](./api-reference#storage-schema). The high-impact tables:

| Table | Contents | | ------------------ | ------------------------------------------------------- | | tabs | URL, title, last visited, pinned state, window/tab IDs. | | page_text | Extracted text from Readability.js, capped at 50 KB/page. | | entities | Persons, projects, papers, repos — with aliases. | | relations | Directed edges between entities + tabs. | | provider_secrets | OAuth tokens / API keys, stored in OS keychain (not the DB). | | audit_log | Local-only log of sync pushes, LLM calls, and config changes. |

If you uninstall TabMind, deleting the browser profile (extension) or removing the application data directory (desktop app) deletes the DB. There is no uninstall "phone-home" — the extension manifest makes no network requests after removal.

Encryption

At rest

The local SQLite file is not encrypted by default. If you set a master passphrase in Settings → Privacy, TabMind wraps the DB in an SQLCipher-style encrypted blob using Argon2id-derived keys (memoryCost = 64 MB, timeCost = 3, parallelism = 1). The passphrase never leaves the device — losing it means losing the index. There is no reset.

In transit (sync)

Every sync upload is:

1. Serialized with MessagePack. 2. Compressed with zstd at level 3. 3. Encrypted with AES-256-GCM using a key derived from your master passphrase via HKDF-SHA-256 (or, if no passphrase is set, a per-device random key stored in the OS keychain — unreachable from a stolen sync token alone). 4. Uploaded over TLS to the configured provider.

A breach of your sync provider exposes only ciphertext. Without either your master passphrase or the per-device key from your OS keychain, the blob is computationally infeasible to decrypt.

In transit (LLM extraction)

LLM calls travel over HTTPS to the endpoint you configured. No TabMind-operated proxy sits in the middle. If your threat model includes your LLM provider logging prompts, the mitigation is to run Ollama locally — see [Providers → Local Ollama](./providers#local-ollama).

Permissions

Browser extension

Declared in manifest.json, requested at install time:

| Permission | Why | | --------------------------- | ---------------------------------------------- | | tabs | Read tab URLs + titles for indexing. | | storage | Persist local SQLite-backed index. | | sidePanel | Render the command bar without a popup. | | scripting | Inject Readability on active tab only, on demand. | | | Required so we can read any page you choose to extract. |

We do not request webRequest, proxy, debugger, or nativeMessaging. There is no host_permissions array beyond , and the activeTab permission is sufficient for our extraction flow when paired with an explicit user click.

Desktop app (Tauri)

Tauri asks for the same capabilities the extension does, scoped to the system WebView. The desktop build does not have network capability broadly enabled — each provider you add whitelists its own outbound hosts.

What we don't do

  • No analytics, telemetry, or crash reporting leaves the device.
  • No "phone-home" version check. The app works fully offline forever.
  • No remote kill switch. Uninstalling removes all our code from the
  • machine.
  • No background uploads. Sync only fires when you click Push or on
  • the timer you set in Settings → Sync → Interval (default: 15 minutes, configurable down to manual only).
  • No tracking pixels, fingerprinting, or third-party fonts on our
  • marketing site or docs site.

    Audits and source availability

  • The extension and desktop app are open source at
  • . Every release is reproducible from source.
  • Release artifacts are signed (Sigstore / cosign) and the signatures
  • are published alongside the GitHub release.
  • We welcome security reports via
  • (PGP key on the repo's SECURITY.md). We aim for first-response within 48 hours and a fix-or-mitigation within 14 days for high-severity issues.

    Compliance notes

  • GDPR. We are not a data controller for any data you choose to send
  • to a third-party provider. The sync and LLM providers you configure are. TabMind's own footprint is empty.
  • HIPAA / regulated data. TabMind's at-rest encryption uses standard
  • primitives (AES-256-GCM, Argon2id) and our key handling matches the pattern recommended by NIST SP 800-132. That said, we have not undergone a formal HIPAA audit — please consult your compliance team before routing PHI through TabMind.
  • Enterprise. For SSO / SCIM / audit-log export, see the
  • seele-enterprise package (separate repo, contact ).

    Threat model cheat sheet

    | Threat | Mitigation in TabMind | | ------------------------------------------------------ | -------------------------------------------------------------------------- | | Lost / stolen laptop | OS keychain + optional master passphrase (AES-256-GCM at rest). | | Compromised sync provider | Encrypted blob — provider sees only ciphertext. | | Compromised LLM provider | Run Ollama locally. | | Malicious browser extension reading TabMind's storage | Each provider's OAuth token is stored in OS keychain, not in our DB. | | Network observer (ISP, coffee shop) | TLS 1.3 only; HSTS preload; modern cipher suites. | | Quantum adversary on stored ciphertext | Swap AES-GCM for ML-KEM (Kyber) hybrid; tracked in SECURITY.md. |

    If a threat you care about isn't covered above, file an issue — we take the threat model as a living document.

    Next steps

  • [API reference → Encryption details](./api-reference#encryption-details)
  • walks through the exact KDF parameters, IV sizes, and key rotation cadence.
  • [Providers → Revoking access](./providers#turning-providers-off)
  • shows how to revoke a provider's OAuth credentials when you stop using it.
  • [Troubleshooting → Sync errors](./troubleshooting#sync) covers the
  • security-related error codes you might see in the audit log.