Pane reads the credential files that AI CLIs and editors keep on your PC. That is a serious responsibility, and this page explains how we handle it and how to reach us when something looks wrong.
Please do not open a public issue for security problems.
Use GitHub's private vulnerability reporting: go to the Security tab → Report a vulnerability. You'll get a response as fast as humanly possible for a small open-source project — usually within a couple of days.
Please include: what you found, how to reproduce it, and what an attacker could do with it.
All of this is auditable in the source — links go to the exact code.
- Tokens never leave their lane. Each provider's credential is sent
only to that provider's own API over HTTPS
(
src-tauri/src/providers/— one module per provider; see docs/providers.md for the exact files read and endpoints called). - At-rest storage policy: the secrets Pane itself persists — API keys,
OAuth/login refresh tokens, Cursor/Codex account token pairs — live in
the platform's native credential store (Windows Credential Manager via
src-tauri/src/secretstore.rs); the JSON files under%APPDATA%\PaneAafff623\keep only non-secret fields (labels, ids, expiry, card-id snapshots). Legacy plaintext entries migrate on first read — the vault write must succeed before the file loses the secret, so a broken vault degrades to the plaintext fallback instead of losing the credential. Three stores are deliberately outside the OS vault, each with its own protection: One/New API sites and keys (owner-only plaintext JSON), the master-password key vault (AES-256-GCM sealed file), and search/MCP keys (plaintextsearch-keys.json). Credentials Pane discovers (owned by other CLIs/editors) stay in their own files; Pane never copies them into its stores. - Multi-account discovery widens where credentials are found, never
where they are sent. To support second logins kept via
CLAUDE_CONFIG_DIR/CODEX_HOME, Pane scans dot-folders in your home directory and~\.configfor Claude/Codex-shaped credential files — the places those official mechanisms put them. A discovered credential follows the exact same lane rule (its own vendor's API only, token refresh written back beside it), a file that cannot name its account is never used at all, and a broadly-discovered Codex candidate must additionally prove it's an OpenAI login (OpenAI's own claim namespace in itsid_token) before any request — a look-alike credential file from another app never enters the lane. - No analytics SDK, no telemetry, no crash reporter, no event
streams. Pane sends no usage statistics. The update check adds no
reporting of its own: it is a plain GET for this project's own update
manifest — served from the project's Cloudflare edge route first, with
this project's GitHub Releases
latest.jsonas the fallback (Cloudflare and GitHub may each log the request under their own privacy statements; Pane runs no counter and stores nothing). The full list of network calls Pane can make is in docs/privacy.md. - The local HTTP API is loopback-only, CORS-locked, and Host-checked.
It binds
127.0.0.1:6736, serves usage numbers (never credentials), sends noAccess-Control-Allow-Originheader, and refuses requests whoseHostheader isn't a loopback spelling — so web pages you visit cannot read it from a browser, not even via DNS rebinding (src-tauri/src/httpapi.rs). - Updates are cryptographically verified. The auto-updater accepts
only releases signed by the project's minisign key — passphrase-protected,
master copy held offline; the public key is baked into the app. The
install script verifies the installer's SHA-256 against the release
manifest and refuses to run on mismatch (
install.ps1). - Links are restricted. The app can only open
http(s)://URLs in your browser — nothing that could launch a program. - The webview is locked down. A strict Content-Security-Policy (no
remote scripts, no eval, no frames) plus a minimal Tauri capability set
— the UI can reach only Pane's own commands, no plugin APIs
(
src-tauri/tauri.conf.json,src-tauri/capabilities/default.json). - Config writes are schema-bound. The UI can only write known config keys; anything else is dropped and logged.
- Credential files are backed up before write. When Pane writes a
refreshed OAuth token back to a CLI's credential file, it first copies
the original to
*.pane-bak— a bad write can never cost you a login. - API keys you paste go into the OS credential vault (Windows
Credential Manager, macOS Keychain, Linux Secret Service); the JSON
files keep only non-secret fields, and a row whose vault write fails
keeps its plaintext as the documented fallback. Login-based accounts
(OAuth/device-code) use the same vault, one
token:login/<card-id>slot per account (src-tauri/src/login_accounts.rs); theirlogin-accounts\<family>.jsonkeeps only labels, ids and expiry, and legacy plaintext tokens migrate on first read — the vault write must succeed before the file loses them, so a broken vault degrades to the plaintext fallback instead of losing the credential. The save order is a data-safety property: vault slots of removed accounts are dropped only after the replacement file is durably on disk, so a failed write can never cost an existing account. The WorkBuddy web-session cookie you explicitly import follows the same vault-first pattern through a session slot (token:web/workbuddy);workbuddy_web.jsonis kept only while a vault write fails. One/New API sites and keys use a nested owner-only store; Settings returns labels and origins after save, never secret values or fragments.
- The installer is not yet Authenticode-signed, so SmartScreen warns
on first run. Updates are minisign-verified regardless. A code-signing
certificate is planned. (The
irm https://raw.githubusercontent.com/Aafff623/pane/main/install.ps1 | iexinstall path and winget don't trigger SmartScreen.) - Release binaries are built by GitHub Actions from the pushed tag — see .github/workflows/release.yml; every release links public build logs proving the binary comes from the tagged source.
- Pane refreshes OAuth tokens and writes them back to the CLIs' own credential files (keeping your CLIs signed in). This means Pane has the same access to those accounts as the CLIs themselves — that's inherent to what the app does.
- The install script's SHA-256 check verifies the download against
latest.jsonfrom the same GitHub release — it defends against corrupted or swapped downloads, not against a fully compromised release (an attacker who can replace the installer can replace the manifest, and the script itself, too). The cryptographic guarantee is the auto-updater's minisign verification once installed; the first install ultimately trusts GitHub. Anyone who'd rather not pipe a script into PowerShell at all can use winget or download-and-read first — the README shows both. - Model prices (LiteLLM, models.dev, the OpenUsage supplement) are fetched without signatures — tampered pricing data could at worst show wrong display dollars. Inputs are size-capped and never touch credentials or spend logs.
Only the latest release is supported. The auto-updater keeps installs current.