IThe custody model
Nothing leaves.
Nothing phones home.
SQAI runs where your data lives. At query time there is no network call to intercept, no service holding your rows, no telemetry. This sheet accounts for every byte that ever crosses the wire — there are exactly two movements, and neither is your data.
- Your rows
Read inside your process. Never copied out, never uploaded, never held by anyone but you.
never - Plans & results
Validated and executed in-process. Results live in a bounded local store and expire after 15 minutes.
never - Telemetry
None exists. No analytics call, no crash reporter, no home to phone.
never - Runtime bundle
Engine code, fetched once from Cloudflare R2 and verified before a single file is written. Code comes in; rows never go out.
once · inbound · signed - Device sign-in
Optional. Moves a signed license token between your machine and the account service — never your data.
optional · token only
No query-time network. Cut the wire after install and every query still answers.
Read-only is not a setting.
It is the shape of the tool.
4,574 exposed capabilities · every one a read · no write path to misconfigure
IIIThe one download
Six checks before a file lands.
The runtime bundle is the only thing SQAI ever fetches — engine code from Cloudflare R2, treated as hostile until proven otherwise. Verification runs before extraction, continues file by file, and the install is atomic.
- 01
One accepted key
Releases are signed RS256 with a single RSA-4096 release key. One key verifies; nothing else is trusted.
- 02
Verify before extract
The signature is checked over the manifest before any file is unpacked. A tampered or unsigned bundle never gets that far.
- 03
Schema and path safety
The manifest must parse to the expected schema, and every listed path must resolve inside the install root.
- 04
Per-artifact sha256
Every file is hashed and compared against the signed manifest. One mismatched byte fails the whole install.
- 05
Unlisted or symlink — reject
A file the manifest does not list, or any symlink, rejects the bundle outright.
- 06
Atomic install, floored rollback
Extraction lands in a temp directory and moves into place with one atomic rename. Versions below the accepted floor are refused as rollback_protected.
runtime_bundle 0.1.0sha256 4d64142e4c1ff63d299cfc8b172fdf97cb59169b545e1e02978e678a632ce6e1MIN_ACCEPTED_RUNTIME_VERSION 0.1.0 · below → rollback_protectedIVKeys & error hygiene
Small surfaces, kept small.
The device key
- location
- ~/.sqai — in your home directory, nowhere system-wide
- permissions
- file mode 600 — readable by you alone
- issuance
- optional device sign-in (RFC 8628 device code)
- what moves
- a signed license token — never your data
What the model sees
ENOENT: no such file or directory — /Users/dana/finance/q3-actuals.csvENOENT: no such file or directorysanitizeMessage strips absolute paths from every model-visible error. Your filesystem layout is never part of the model's context.
VThe result store
A handle that proves nothing.
Large results stay behind a handle instead of flooding the model's context. The handle is engineered to be worthless to anyone but its issuing tenant.
- result_id
- 16 random bytes, base64url — unguessable, unlinkable to any query or tenant
- authorization
- tenant-scoped — only the issuing tenant can redeem it
- wrong tenant
- result_not_found — indistinguishable from a handle that never existed
- lifetime
- 15-minute TTL · ≤256 results · 64 MB total · 16 MB per tenant
result_id = base64url(randomBytes(16))
→ ok→ result_not_foundNot forbidden — not found. Existence is never disclosed.
VIThe air-gap runbook
Runs where the wire is cut.
The query plane is offline by design; only the compute runtime is ever fetched. To run fully disconnected, take delivery of the bundle yourself — the verifier does not care where the bytes came from.
- 01
Pin auto-install off
SQAI will never fetch the runtime implicitly.
$export SQAI_RUNTIME_AUTO_INSTALL=0 - 02
Carry the bundle across
Fetch the signed bundle on a connected machine and move it under your own transfer policy.
- 03
Install from the file
All six checks run against the local file — same signature, same manifest, same per-artifact hashes.
$sqai runtime install --from-file <bundle> - 04
Verify in place
Re-check the installed runtime against the single accepted release key, any time.
$sqai runtime verify
After install: zero network. Queries, policy checks, and provenance hashes are computed locally.
VIIThe review questions
Asked in every security review.
What exactly leaves my machine?
At query time, nothing. Over the life of an install, two things cross the wire: one inbound signed runtime bundle from Cloudflare R2 (engine code, not rows), and — only if you opt into device sign-in — a signed license token. There is no telemetry.
Is read-only just a flag someone could flip?
No. A read-only flag on a database connection is a promise; SQAI is a missing surface. All 4,574 exposed capabilities are reads — there is no write, DDL, or eval path to guard — and the escape hatch (getUnsafeRuntime) is never reachable by a model.
Can the model widen its own access?
No. Policy is fixed in code at createSQAI() time and checked in-process before execution. The tool input the model fills carries no allowed* fields, and naming a capability outside the allow-list throws unsupported_operation.
Does SQAI run air-gapped?
Yes. Set SQAI_RUNTIME_AUTO_INSTALL=0, move the signed bundle yourself, and install with sqai runtime install --from-file. The identical verification chain runs against the file, and the query plane is fully offline regardless.
Can an error message leak my file paths to the model?
No. sanitizeMessage strips absolute paths from every model-visible error, so the model never learns your filesystem layout.
The next step
Bring your security review.
Walk the questionnaire through with us — custody, signing, policy, air-gap — every answer traceable to code.