Your engine encrypts dashboard data before syncing it. Your account password signs you in; your separate dataPass unlocks the well data.
| Item | Where | Who can read it |
|---|---|---|
| Raw rig files (mudlogs, geology tables, surveys) | Your workstation only | You |
| 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 store | Anyone with the dataPass; nobody else, including us |
| dataPass | Engine config on your workstation; typed into the browser per session | You, and anyone you choose to share it with |
| Engine license key (push secret part hashed) | Hash on our side, plain in your engine config | Your engine |
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.
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.
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).
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.
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.
| Check | Result | |
|---|---|---|
| Values and words from the well files found in what left the computer | 0 of 361 tested | Pass |
| dataPass or the key derived from it found in any request | 0 | Pass |
| Uploaded objects that are valid AES-256-GCM envelopes and open with the dataPass key | 59 of 59 (24.7 MB); none opens with a wrong key | Pass |
| File paths, Windows user name or computer name in any request | none | Pass |
| Hosts the engine tried to reach besides your BoreWatch server | borewatch.com (update check and the daily install notice; see the table below) | Pass |
| Built-in AI model reachable from the network | listens on 127.0.0.1:8777 only | Pass |
| Network calls in the engine source that are not listed below | none | Pass |
| Destination | When | What is sent |
|---|---|---|
| Your BoreWatch server | each run | Account id and license secret (as a header). Nothing about wells. |
| Your BoreWatch server | after a build | Encrypted objects only: AES-256-GCM envelopes {v, iv, ct} and the object name. |
| Your BoreWatch server | every 5 s while the engine runs | Asks for waiting questions; receives ciphertext. |
| Your BoreWatch server | after answering | The answer, encrypted with your dataPass key. |
| Your BoreWatch server | borewatch doctor only | A plain GET to test the connection. |
| borewatch.com | once a day | Install notice: random install id, engine version, Windows version, account id. Off with BOREWATCH_NO_PING=1. |
| borewatch.com | once a day | A plain GET of the latest version number. |
| data.borewatch.com | when you update | Downloads the signed installer. Sends nothing. |
| github.com, huggingface.co | once, when you choose the built-in model | Downloads 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 starts | Local health check. |
| 127.0.0.1 (this computer) | AI analysis and Ask | The AI prompt, to the built-in model on the same computer. |
| localhost (this computer) | AI analysis and Ask | Checks whether Ollama is installed. |
| Ollama (this computer by default) | only if you use Ollama | The AI prompt. |
| Your OpenAI-compatible endpoint | only if you set one | The AI prompt (a compact well summary and the question), under your own account. |
| api.anthropic.com | only with your own API key | The AI prompt (a compact well summary and the question), under your own account. |
| api.telegram.org | only if you set up alerts | The alert text for high-severity events. |
| Your mail server | only if you set up alerts | The 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.
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.