BYOKchat Blog

Where Does a BYOK Web App Store Your API Key?

Understand how BYOKchat stores API keys and chat data locally in the browser, what IndexedDB protects and does not protect, and how web storage differs from Apple Keychain.

· 8 min read

On this page
  1. What BYOKchat Web keeps in this browser
  2. Is the API key in IndexedDB?
  3. What does “same-origin” protection mean?
  4. How is this different from Apple Keychain?
  5. Does BYOKchat send my API key to BYOK servers?
  6. What does leave the browser?
  7. What does BYOK’s first-party analytics contain?
  8. Why not encrypt the API key with JavaScript before putting it in IndexedDB?
  9. What about browser extensions?
  10. What happens if I clear browser data?
  11. What does “Delete chat data” remove?
  12. Are backups safe to share?
  13. Should I use the web app or the native app for sensitive work?
  14. A practical web BYOK safety checklist
  15. Bottom line
  16. Further reading

In the current BYOKchat web app, your provider API key is stored locally in the browser, not in a BYOKchat cloud account. Conversations, messages, attachments, provider configuration, and several other pieces of app state are also kept in browser-local storage.

That is useful for privacy and portability, but “local” does not mean “protected exactly like a native password vault.” Browser storage and Apple Keychain have different security boundaries.

The current architecture is roughly:

Browser profile
┌───────────────────────────────────────┐
│ chat.byok.pro origin                  │
│                                       │
│ IndexedDB / browser-local databases   │
│ ├── conversations + messages          │
│ ├── attachments                       │
│ ├── provider config + API key         │
│ ├── MCP connections / credentials     │
│ ├── tool permissions                  │
│ └── recovery checkpoints              │
│                                       │
│ local preferences / analytics state   │
└───────────────────────────────────────┘

No BYOK account / cloud conversation sync

When you actually ask an AI model something, the relevant request still leaves the browser and goes to the provider you selected. Local storage describes where the workspace rests between requests, not a claim that an online AI provider never receives your prompt.

What BYOKchat Web keeps in this browser

The current web client’s privacy design stores application state locally in the browser, including:

  • conversations and messages;
  • message attachments;
  • selected provider, endpoint, model, and provider API key;
  • remote MCP connection settings and credentials;
  • exact-tool approval grants;
  • tool execution and provider-approval recovery checkpoints;
  • appearance preferences;
  • a small amount of first-party analytics state used for bounded aggregate counters and retrying analytics uploads.

There is currently no BYOK account or cloud conversation synchronization in the web app.

That means closing the tab does not require uploading your conversation database to BYOK servers just so it can appear again later. The browser’s local site data is the persistence layer.

Is the API key in IndexedDB?

The current web implementation keeps credentials and several other databases in browser-local storage, with credential and recovery state stored in IndexedDB-backed local databases.

IndexedDB is a browser storage API intended for structured local data. It is useful because a web application can persist more than a tiny preference string and can organize records such as chats, attachments, credentials, and recovery state.

But it is important to understand what IndexedDB is not:

IndexedDB
✓ local to a browser profile/site origin
✓ not automatically uploaded to BYOKchat
✓ persistent across page reloads
✓ suitable for structured app data

IndexedDB
✗ not Apple Keychain
✗ not a hardware-backed secret vault by definition
✗ not inaccessible to all JavaScript running in the origin
✗ not protection against a compromised site origin

The relevant trust boundary is the website origin and the browser environment.

What does “same-origin” protection mean?

Browsers isolate site storage by origin. Ordinary JavaScript from an unrelated website cannot simply open chat.byok.pro’s IndexedDB and read its records.

Conceptually:

https://example.com

       ✗ cannot normally read

https://chat.byok.pro local database

That browser isolation is valuable, but it is not magic encryption against code that is legitimately executing as chat.byok.pro.

If malicious code gains execution inside the trusted origin—for example through a serious cross-site scripting vulnerability or a compromised dependency delivered by the application—it can potentially act with the origin’s privileges.

That is why a local-first web app still needs strong application security:

  • strict content/security controls;
  • careful dependency management;
  • safe rendering of model/user content;
  • no secret leakage into logs or analytics;
  • minimal third-party scripts;
  • careful handling of URLs and HTML;
  • good deployment integrity.

Local storage reduces one class of cloud-data exposure. It does not eliminate web-application security.

How is this different from Apple Keychain?

The iOS and macOS versions can store provider credentials in Apple Keychain, which is specifically designed for secret storage on Apple platforms.

The simplified comparison is:

PropertyBYOKchat WebNative iOS/macOS
Credential locationBrowser-local storage / IndexedDBApple Keychain
Chat/workspace storageLocal browser databaseLocal app storage
BYOK cloud chat syncNoNo by design
Trust boundaryBrowser origin/profileNative app + OS security model
Site JavaScript can access credentialApp code must access it to call providerNot exposed as browser-origin storage
Clear via browser site-data controlsYesNot applicable

This is why “the data is local” should not be used to imply the two environments have identical secret protection.

For the full comparison, see BYOK Web App vs Native App: What Changes?.

Does BYOKchat send my API key to BYOK servers?

The web app is designed so provider requests go directly from the browser to the provider endpoint you configured.

The data path is:

┌──────────────┐
│ Your browser │
│ BYOKchat     │
└──────┬───────┘
       │ HTTPS request
       │ provider API key
       │ prompt/context

┌──────────────┐
│ AI provider  │
└──────────────┘

The provider needs the credential to authenticate the request. BYOK’s own minimal analytics system is designed not to include provider API keys, prompts, responses, attachment contents, MCP credentials, tool arguments/results, or conversation history.

This is a different architecture from a hosted AI proxy where the app server receives your prompt and then calls the model provider with credentials stored server-side.

For that distinction, read Direct-to-Provider AI vs Proxy Servers.

What does leave the browser?

Local-first is not the same as offline-only.

When you use a cloud AI provider, the browser sends the content required for the request to that provider. Depending on the workflow, that can include:

  • the provider API key;
  • your prompt;
  • conversation context;
  • supported images or text attachments;
  • model selection and request settings;
  • tool definitions;
  • tool results needed to continue a tool-calling loop.

If you configure a remote MCP server and approve a tool call, the browser can also send tool arguments to that MCP endpoint.

So the real privacy model is:

Stored workspace      → local browser
AI generation request → selected AI provider
Approved MCP call     → configured MCP server
Minimal analytics     → BYOK analytics service

This is more precise than saying “nothing ever leaves your device.”

See How Private Is a BYOK AI Chat App?.

What does BYOK’s first-party analytics contain?

The web client uses small first-party analytics batches for basic product usage and reliability understanding.

The current design uses a random site-scoped installation identifier and bounded aggregate counters such as session/activity counts and product-action totals.

The analytics design intentionally excludes sensitive workspace content such as:

  • provider API keys;
  • MCP credentials;
  • configured MCP URLs;
  • prompts;
  • model responses;
  • conversation history/titles;
  • attachment contents or filenames;
  • tool schemas, arguments, and results;
  • approval decisions and recovery checkpoints;
  • arbitrary URLs/referrers;
  • advertising identifiers.

For the general engineering principles behind this approach, read Privacy-Preserving Analytics for AI Apps.

Why not encrypt the API key with JavaScript before putting it in IndexedDB?

Client-side encryption can be useful in some architectures, but it does not automatically solve the core web-origin problem.

If the application needs to decrypt the key automatically in order to make provider requests, then the running application also needs access to whatever decryption material or process makes that possible.

A naive scheme like:

key stored encrypted in IndexedDB
+
decryption key stored beside it
=
mostly obfuscation

can add complexity without meaningfully changing the attack boundary.

Stronger designs may involve a separate user secret, OS/browser credential APIs, hardware-backed mechanisms, or not persisting the credential at all—but each comes with usability and compatibility tradeoffs.

The important thing is to describe the actual protection honestly rather than label any ciphertext “secure.”

What about browser extensions?

Browser extensions operate under their own permission model. Extensions with powerful access to pages or site data can expand your local trust boundary.

For sensitive BYOK use, prefer a browser profile and extension set you trust. The same principle applies to malware, shared operating-system accounts, remote-control tools, and anyone who can unlock your device.

Local-first protects against unnecessary application-server storage; it does not protect an already-compromised endpoint.

What happens if I clear browser data?

Browser site-data controls can remove the local state for chat.byok.pro.

That can include:

  • chats;
  • attachments;
  • provider credentials;
  • MCP connections and credentials;
  • tool permissions;
  • recovery state;
  • local analytics installation state.

Because the web app does not depend on BYOK cloud conversation sync, clearing site data can be destructive if you have not exported anything you want to keep.

Before clearing browser data, export important conversation backups when appropriate.

What does “Delete chat data” remove?

The current in-app delete-chat-data control is intentionally narrower than deleting all browser site data.

It removes local conversations, messages, and attachments while keeping configuration such as provider/MCP credentials, permissions, appearance, and analytics state. Orphaned recovery journals are cleaned up during subsequent app startup.

That difference is useful:

Delete chat data
    → remove chat content
    → keep connections/settings

Clear browser site data
    → remove the whole local site state

If your goal is to remove the API key as well, use the app’s provider-credential controls or clear the complete site data as appropriate.

Are backups safe to share?

Do not assume an exported backup is harmless merely because API keys are excluded.

BYOKchat backups can contain conversation content, attachments, tool events, and other workspace material. The current design excludes provider credentials and several sensitive configuration databases, but the remaining content can still be private.

Treat backups as user documents:

  • store them where you intend;
  • inspect before sharing;
  • delete old copies when no longer needed;
  • do not upload them to public bug reports.

For the architecture of secure backups, see Backup and Restore Security for Local AI Chats.

Should I use the web app or the native app for sensitive work?

That depends on your threat model and workflow.

The web app is convenient, portable, and requires no install. It also has the browser-origin security boundary described above.

The native apps can use platform facilities such as Apple Keychain for credentials and are not dependent on a website’s JavaScript execution environment for secret access.

For users who prioritize stronger OS-native credential storage, the native app can be the better fit. For users who prioritize immediate access across a trusted browser profile, the web app can be a reasonable choice.

Neither choice changes the fact that cloud-provider request content is sent to the selected provider when you generate a response.

A practical web BYOK safety checklist

If you use API keys in a browser-based AI client:

  • use the official HTTPS site;
  • use a device and browser profile you trust;
  • keep the browser updated;
  • avoid untrusted extensions with broad page access;
  • use provider keys you can rotate;
  • consider separate provider keys per client;
  • set provider-side spending limits where available;
  • periodically review provider usage;
  • export important chats before clearing browser storage;
  • revoke any credential you believe has leaked.

The strongest design principle is not “the secret can never be stolen.” No realistic client can promise that. It is minimize where the secret exists, make the boundary explicit, and make rotation easy.

Bottom line

BYOKchat Web keeps its workspace and provider credentials local to the browser rather than synchronizing them to a BYOKchat cloud account. That significantly reduces the amount of user content BYOK infrastructure needs to hold.

But browser-local storage is not identical to Apple Keychain. Code running under the trusted site origin must be able to access the API key to make direct provider requests, so the security of the origin, browser, device, and dependencies matters.

That is the right way to understand “local-first” on the web: fewer unnecessary servers in the trust chain, not a claim that browser storage is an impenetrable vault.

Further reading

Keep reading