# What actually leaves your machine when you use an AI API tool? We audited ours.

"Local-first" is an easy claim and a hard audit. So instead of a manifesto, here is the concrete data-flow map of the Powerduck desktop client — where each capability runs, and what a network observer, a renderer process, or the model provider can actually see.

## API requests run in the Node main process

When you send a request from the Request workspace, execution goes through the local main process, not the web view. Two consequences follow directly from that:

-   there is **no browser CORS wall** — cross-origin calls are not blocked by the renderer’s security model;
-   the request URL, `Authorization` header and body do not appear in the renderer’s developer-tools network panel.

The same applies to model completion requests: prompts, the system prompt, the tool catalog and your model API key are sent from the main process. The gateway is deliberately not an open proxy — targets are validated against loopback and permitted hosts, request headers are sanitized, response splitting through headers is prevented, and an in-flight request can be cancelled with `ai:cancel`.

## The model is pluggable, and yours

Configure any OpenAI-compatible Chat Completions endpoint — a built-in vendor preset or a custom base URL with its own key — and keep several profiles. Capable models get native function calling with the full tool catalog; endpoints that reject tool parameters are remembered and retried once over a content-based fallback protocol instead of failing. Tool use is bounded to three rounds by default and de-duplicated, so a model cannot spin a loop calling the same tool. If your policy says "self-hosted model only," that is just another profile.

## What works with the network cable pulled

-   designing and editing the spec, with full revision history on disk;
-   the local mock server, including recorded-request inspection;
-   rendered documentation;
-   scenario runs against local targets and exported reports.

Only live requests to external hosts, Git sync, hosted models and Cloud publishing need a connection.

## Database access is read-only by construction

The Data model surface stores saved connection profiles (dialect, host, port, user, database) but **never returns passwords**. Live queries run through `database.runSelect`: read-only `SELECT` statements with a bounded, truncated row set — writes and DDL are blocked. The migration SQL the reconciliation produces (ordered, additive `ALTER` steps with `blockedBy` dependencies, or an idempotent forward-only creation script) is generated for review and is never executed against your database from the app. The new-connection dialog is prefilled and the password is typed by you, not accepted through a chat prompt.

## The small print, in one table

| Activity                    | Where it runs                                    | What leaves the machine                        |
|-----------------------------|--------------------------------------------------|------------------------------------------------|
| Spec editing and AI patches | Local file + your configured model               | Only the prompt payload to your model endpoint |
| Sending API requests        | Node main process                                | Only the request to the target host you chose  |
| Mock server                 | Local main process                               | Nothing                                        |
| Scenario reports            | Local engine, local HTML export                  | Nothing; credentials redacted in the file      |
| Database comparison         | Bounded read-only SELECT over your saved profile | Only the query to your database                |
| Licensing                   | Offline verification on the device               | No account, no session                         |

## The cloud is a deployment target, not a home

The desktop client is sold as a one-time perpetual license and opens with no account. Cloud exists for the moments where sharing is the point — hosted docs, a managed MCP endpoint, Git sync — and the file you publish is a copy of the truth on your disk. Even the hosted demo’s sign-in exists only to meter shared cloud resources; the downloaded client never asks for it.

If your team is the kind that reads data-flow tables before approving a tool, [the AI and models reference](https://www.powerduck.com/docs/client/ai-models?ref=powerduck.com) documents the same boundaries in engineering detail.

