skip to content
Data boundaries

Security & governance

Data boundaries

A line-by-line accounting of what stays on your hardware, what can leave, and what the metadata looks like when it does.


The local-first guarantee is the short version: inference runs on the machine in front of you and touches the network zero times. Here is the same boundary at full resolution. For each class of data Conifer holds, you get the side of the line it lives on, and for the handful that can cross, exactly what crosses.

Think in data classes, not features. A prompt is a prompt whether you typed it in the studio or POSTed it to conifer serve. The boundary wraps the data, so it holds the same way regardless of which surface produced it.

What never leaves

Most of what Conifer touches has no code path to the network. These classes are read off your disk or held in memory, and inference consumes them in process. No serializer turns them into an outbound request, because no such request exists.

Prompts and chat history
Your input is tokenized and fed to the model in the same process. Conversations, agents, and settings persist to local storage on disk. Nothing is keyed to an account and nothing syncs.
Generated tokens
Decode writes into a local buffer and streams to the screen. The reply exists only on your machine until you copy it somewhere.
The KV cache and intermediate state
The KV cache, activations, and scratch buffers live in RAM for the duration of a turn and are freed after. None of it is written anywhere off the box.
Connector reads
When a granted agent reads your calendar, notes, or a folder, it reads a store on the machine and sends nothing. The read is local; see the grant model.
Files an agent touches
File contents an agent reads or writes stay on disk. A write stages for your approval first and never leaves the watched folder it was granted.

What can leave, and only when you ask

A boundary with no exits would be a fiction, so here are the exits. A small, fixed set of actions can open a connection. Each one is off until you start it or grant it, none of them carry a prompt or a generated token, and inference is in none of them.

Weights
Installing a model is an HTTPS GET to a model host for the weights file. You choose the model. After that one fetch, the file is read straight off disk on every load and never touches the network again.
Web search
A search query goes device-to-provider directly, never through a Conifer server, and only after you grant the capability to an agent. The query string leaves; nothing else does.
Granted host reach
The reach these hosts grant lets an agent connect to the exact hosts you name and no others. What it sends is whatever that tool is built to send, scoped to the allowlist you set.
Update checks
A version check against the update endpoint, with no prompt or token data attached. App upkeep, not your content.

The browser chat surface defaults to offline: it makes no network call beyond that one-time weight download. The studio behaves the same way, and local-first walks through each exit and its gate in full.

When a byte does leave, what the record looks like

Every outbound call the studio originates lands in an append-only egress log, so “did anything leave, and what?” has an answer you can read. The log records the shape of the call, not its contents.

The fields an egress entry keeps
FieldWhat it holds
hostThe hostname only. Never the full URL, never the path or query string.
kindOne of weights, web_search, fetch_url, or other.
bytesA best-effort byte count, or nothing when the payload is opaque.
labelA short context note, such as the search query or the model id.
atA timestamp.

Entries are kept on-device for seven days, then pruned. The egress sheet in the studio rolls them up per day, and reads 0 bytes when nothing left.

The audit trail respects the same boundary it records. It can tell you a web search reached a search host at 14:02 and sent 600 bytes. It cannot tell anyone, including you on a later read, the contents of what was searched beyond the label you already see: the path and query were never written down.

Telemetry is off, and stays categorical when on

No usage telemetry is collected by default. A fresh install sends nothing and reports a posture of none. Turn on-device usage telemetry on and the toggle changes two things: what gets collected, and what the machine attests to.

With it on, the data is anonymized and categorical: which app areas and tools were used, the device class, error categories. Message content, file paths, prompts, and personal identifiers never enter it. Events sit on-device and flush only when you are online, opted in, and the network is allowed, then wipe locally the moment the flush succeeds.

The boundary holds when you serve

Exposing the runtime as a local API does not move the line. conifer serve binds to loopback, so the request never leaves the host, the inference runs locally, and the response comes back over 127.0.0.1. Pointing a client at the server changes nothing about which side of the boundary your prompt sits on.

terminal
conifer serve --model qwen3-8b
# listening on 127.0.0.1:8080 (loopback only)

You can expose the server beyond the machine, but that takes a deliberate bind to a public interface. At that point you moved the boundary yourself rather than had it moved for you.

Where to read next

This page is the accounting. For the guarantee underneath it, read the local-first guarantee. For what an attacker can and cannot do with this boundary in place, read the threat model. To hold the same posture across a team without a collection server in the middle, see MDM policy and the expiring binary.