Security model

Your well data. Protected by design.

Your engine encrypts dashboard data before syncing it. Your account password signs you in; your separate dataPass unlocks the well data.

What lives where

ItemWhereWho can read it
Raw rig files (mudlogs, geology tables, surveys)Your workstation onlyYou
Built dashboard objects (plain JSON)Your workstation (out/)You
Encrypted objects (AES-256-GCM over gzip JSON)Your workstation and, with sync on, our private object storeAnyone with the dataPass; nobody else, including us
dataPassEngine config on your workstation; typed into the browser per sessionYou, and anyone you choose to share it with
Engine license key (push secret part hashed)Hash on our side, plain in your engine configYour engine

The three keys

1. Account password

Authenticates a person to the service. It is checked server-side against an scrypt hash and produces a short-lived, HttpOnly, SameSite=Strict session cookie. It unlocks the dashboard shell and the right to download the ciphertext of your own data space. Nothing more.

2. dataPass

Chosen by you in the engine and known only to you; never transmitted. Browser and engine derive the same AES-256 key: PBKDF2-SHA256 (250,000 rounds, per-account salt) then HKDF-SHA256. Every object is encrypted with a fresh random nonce and authenticated (GCM tag), so a wrong dataPass fails cleanly and a tampered object is rejected. A leaked account password does not help: without the dataPass, the ciphertext is noise.

3. License key

Lets your engine upload new objects. It carries your account id and a random 128-bit push secret, of which we store only the hash. It cannot read anything, and a new key can be issued from the dashboard's Account page (the old one stops working).

Local mode: zero upload

If the policy is "nothing leaves the site", skip sync. The dashboard can open the engine's output folder directly through the browser's file-system access API (Chrome and Edge). The engine then makes only the license check, the daily update check and the daily install notice (switch the notice off with BOREWATCH_NO_PING=1); none of them carries well data, as the audit below shows.

Platform hardening

Data residency audit

We run the real engine on the public sample data (21 wells, 527 files) against a recording server, and capture every byte it sends: every DNS lookup, every connection and every request body. Anything addressed to a host other than this computer is logged and blocked. Then we search the captured traffic for what must never leave the computer. Last run: 2026-11-13, engine 1.8.3. Summary: residency-audit.json.

CheckResult
Values and words from the well files found in what left the computer0 of 361 testedPass
dataPass or the key derived from it found in any request0Pass
Uploaded objects that are valid AES-256-GCM envelopes and open with the dataPass key59 of 59 (24.7 MB); none opens with a wrong keyPass
File paths, Windows user name or computer name in any requestnonePass
Hosts the engine tried to reach besides your BoreWatch serverborewatch.com (update check and the daily install notice; see the table below)Pass
Built-in AI model reachable from the networklistens on 127.0.0.1:8777 onlyPass
Network calls in the engine source that are not listed belownonePass

Every network call the engine can make

DestinationWhenWhat is sent
Your BoreWatch servereach runAccount id and license secret (as a header). Nothing about wells.
Your BoreWatch serverafter a buildEncrypted objects only: AES-256-GCM envelopes {v, iv, ct} and the object name.
Your BoreWatch serverevery 5 s while the engine runsAsks for waiting questions; receives ciphertext.
Your BoreWatch serverafter answeringThe answer, encrypted with your dataPass key.
Your BoreWatch serverborewatch doctor onlyA plain GET to test the connection.
borewatch.comonce a dayInstall notice: random install id, engine version, Windows version, account id. Off with BOREWATCH_NO_PING=1.
borewatch.comonce a dayA plain GET of the latest version number.
data.borewatch.comwhen you updateDownloads the signed installer. Sends nothing.
github.com, huggingface.coonce, when you choose the built-in modelDownloads llama.cpp and the model; each file is checked against a pinned SHA-256. Sends nothing.
127.0.0.1 (this computer)when the built-in model startsLocal health check.
127.0.0.1 (this computer)AI analysis and AskThe AI prompt, to the built-in model on the same computer.
localhost (this computer)AI analysis and AskChecks whether Ollama is installed.
Ollama (this computer by default)only if you use OllamaThe AI prompt.
Your OpenAI-compatible endpointonly if you set oneThe AI prompt (a compact well summary and the question), under your own account.
api.anthropic.comonly with your own API keyThe AI prompt (a compact well summary and the question), under your own account.
api.telegram.orgonly if you set up alertsThe alert text for high-severity events.
Your mail serveronly if you set up alertsThe alert text for high-severity events.

With the built-in model, Ollama or the rule-based narrator, the AI analysis and Ask stay on your computer. If you choose the Anthropic API or an OpenAI-compatible endpoint, the AI prompt (a compact summary of the well and your question) goes to that provider under your own account and terms.

What we can and cannot do

We can see that an account exists, how many objects it pushed and when, and the names of the objects. To hide well names as well, turn on name anonymization in the engine (borewatch set anonymise_names true): each well identifier is then replaced by a hash before upload. We cannot read any value, depth, event or geology description, and we cannot recover a lost dataPass. If it is lost, use your printed recovery kit, or run borewatch set-key and push again; the engine rebuilds everything from the files on your disk.

Cryptography is implemented with the platform primitives (WebCrypto in the browser, the cryptography package in the engine); the formats are documented in the engine source so you can verify them.