Data, credentials, and trust boundaries

Know what stays local and what does not.

IdeaForge is a static browser application with no account, sync service, analytics, or application backend. Sessions stay in browser storage. Model context and optional audio go directly to the provider you choose. Exports and backups leave only when you explicitly create, copy, download, or share them.

Encrypted credentials are not the same as encrypted interviews. API keys are encrypted at rest. Sessions, backups, and Markdown exports are readable documents by design so the app can search, resume, import, and share them.

Data map

Data Where IdeaForge keeps it When it leaves How to remove it
Sessions
Opening statement, questions, answers, draft text, coverage, facts, tags, status, and synthesis
Plain structured records in this origin's IndexedDB. Relevant context is sent to the selected model provider for each generated question; the wrap-up sends the material needed to synthesise the final document. Export, copy, share, and backup create user-controlled copies. Delete an idea in the library, or clear this site's browser data. Deleting an exported file is a separate operating-system action.
Inference and transcription keys One AES-GCM encrypted credential payload in IndexedDB, with a non-extractable wrapping CryptoKey stored beside it. Attached only to requests for the selected inference or transcription provider. Keys are excluded from session backups and Markdown exports. Use Forget my key, clear site data, and revoke the key at the provider when compromise or reuse is a concern.
Server address and model choices In the encrypted credential payload, per provider, although these values are not secret. Used to address a loopback model server, and to name which model each request asks for. They are sent only to the provider already selected. Forget my key clears the whole saved keyring.
Device preferences Plain localStorage. This includes the hands-free finish word and whether hands-free mode was enabled. Not sent by IdeaForge as interview data. Change the setting, or clear this site's browser data.
Recorded audio Held temporarily in browser memory when record-and-transcribe is used; it is not added to the session database. Sent directly to the selected Groq or OpenAI transcription endpoint. With browser recognition, processing behaviour is controlled by the browser. The app releases the recording after transcription. Provider-side retention is governed by that provider's account and policy.
Static application shell Same-origin JavaScript, CSS, icons, manifest, and HTML in Cache Storage for installation and offline use. Cache entries are public application files, not sessions, keys, provider requests, or responses. Browser site-data controls can remove the service worker and Cache Storage. A new cache version also removes the previous IdeaForge shell cache.
Backups and exports Files or clipboard/share-sheet content outside browser storage after you create them. A backup contains all active and archived sessions. A Markdown export contains one idea's generated document and transcript. Neither contains API keys. Delete or secure the resulting file or shared copy wherever it was sent.

Network boundary

Model and transcription traffic travels from the browser to the configured provider; it does not transit an IdeaForge server. Hosted inference is allowlisted to Anthropic, OpenAI, Groq, and OpenRouter. Local inference is allowed only on localhost and 127.0.0.1, on any port. A typed arbitrary remote model URL is rejected before a request is made.

The current application HTML also loads its stylesheet and font files from Google Fonts. Those asset requests do not contain an IdeaForge API key or interview payload. There are no remote scripts, analytics libraries, or package dependencies. The guide pages use only the repository's local stylesheet and system fonts.

Provider requests use credentials: "omit", so browser cookies are not included. The provider still receives the API credential and the prompt or audio required to perform the selected operation. Provider logging, retention, training, abuse monitoring, and account controls are outside IdeaForge's control; evaluate them before submitting sensitive material.

A local chat model does not automatically make dictation local. If Ollama is selected for inference but Groq or OpenAI is selected for dictation, interview text stays with the local model while recorded audio is sent to the hosted transcription provider. Choose browser recognition or turn dictation off if that distinction matters.

What credential encryption protects

On first save, IdeaForge generates a 256-bit AES-GCM key with Web Crypto. The key is marked non-extractable and stored as a CryptoKey in IndexedDB. The credential keyring is serialised, encrypted with a fresh IV, and stored as ciphertext. The raw API key is not written to disk as plaintext.

A non-extractable key can be used for encryption and decryption by this origin, but Web Crypto will not export its raw bytes. This improves the result of device theft, profile-directory inspection, or a copied disk: the credential payload is not a readable API key file.

MDN documents storing CryptoKey objects in IndexedDB and the meaning of the extractable property.

What it cannot protect

A malicious script already running as the IdeaForge origin could call the same decryption and request functions as the legitimate app. Browser-side encryption cannot make a secret unavailable to code that must legitimately use it. It also does not protect an unlocked browser from a person who can operate the page, a compromised browser or operating system, or the provider account after a key is sent.

The controls that address that risk are structural:

The browser behaviour behind these controls is documented by MDN's Content Security Policy guide and connect-src reference.

What the offline cache contains

The service worker pre-caches the application shell and uses stale-while-revalidate for same-origin GET requests. This lets a previously loaded app open without a network connection. When no model is reachable, the interview can continue with built-in questions and records that degraded source in the session.

Cache Storage is separate from IndexedDB. Removing a stale app-shell cache need not delete sessions, while clearing all site data normally removes both. Back up before using broad browser reset controls. MDN's service-worker guide explains the underlying lifecycle.

Session retention, deletion, and recovery

Sessions are stored only on the current browser profile and origin. There is no cloud copy to restore after site data is cleared, the profile is reset, or the browser evicts storage. IdeaForge requests persistent storage when an interview starts or a backup is imported, but the browser makes the final decision.

IndexedDB's persistence model is described in MDN's IndexedDB reference. For backup and library operation, see Ideas library.

Safe key practice

  1. Create a separate, scoped key for IdeaForge rather than using a broad personal or production credential.
  2. Prefer an expiry, usage cap, project boundary, or provider-side budget limit where the provider offers one.
  3. Never paste a key into a shared Claude artifact. Inside a Claude viewer, select Claude (this viewer), which needs no key.
  4. On a borrowed or shared device, use Forget my key before leaving, then revoke the credential at the provider if another person may have used it.
  5. Never include an API key, session backup, or sensitive transcript in a public bug report. Revoke first if a key has been exposed.

Report a security problem privately

Use GitHub private vulnerability reporting for anything that can exfiltrate a stored key, execute script in the page, alter what is sent to a provider, or cross an origin's storage boundary. Include the browser, exact origin, impact, and reproduction steps, but never include a live credential.

Implementation references

IndexedDB stores and persistence are defined in src/store/db.js. Credential encryption, migration, masking, and deletion are in src/store/secrets.js. Session persistence is in src/store/sessions.js, and key-free backup serialisation is in src/core/backup.js.

The application CSP and outbound host list are in index.html. Cache scope and exclusions are in sw.js. The repository's maintained threat model and disclosure route are in SECURITY.md.